Unstable 0.17.7.0
This commit is contained in:
@@ -484,7 +484,9 @@ namespace Barotrauma
|
|||||||
(int)(HUDLayoutSettings.BottomRightInfoArea.Y + HUDLayoutSettings.BottomRightInfoArea.Height * 0.1f),
|
(int)(HUDLayoutSettings.BottomRightInfoArea.Y + HUDLayoutSettings.BottomRightInfoArea.Height * 0.1f),
|
||||||
(int)(HUDLayoutSettings.BottomRightInfoArea.Width / 2),
|
(int)(HUDLayoutSettings.BottomRightInfoArea.Width / 2),
|
||||||
(int)(HUDLayoutSettings.BottomRightInfoArea.Height * 0.7f)), character.Info.IsDisguisedAsAnother);
|
(int)(HUDLayoutSettings.BottomRightInfoArea.Height * 0.7f)), character.Info.IsDisguisedAsAnother);
|
||||||
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), new Vector2(-12 * GUI.Scale, 4 * GUI.Scale), targetWidth: HUDLayoutSettings.PortraitArea.Width, true, character.Info.IsDisguisedAsAnother);
|
float yOffset = (GameMain.GameSession?.Campaign is MultiPlayerCampaign ? -10 : 4) * GUI.Scale;
|
||||||
|
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), new Vector2(-12 * GUI.Scale, yOffset), targetWidth: HUDLayoutSettings.PortraitArea.Width, true, character.Info.IsDisguisedAsAnother);
|
||||||
|
character.Info.DrawForeground(spriteBatch);
|
||||||
}
|
}
|
||||||
mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
|
mouseOnPortrait = HUDLayoutSettings.BottomRightInfoArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
|
||||||
if (mouseOnPortrait)
|
if (mouseOnPortrait)
|
||||||
|
|||||||
@@ -309,6 +309,32 @@ namespace Barotrauma
|
|||||||
HUDLayoutSettings.BottomRightInfoArea.Height / (float)infoAreaPortraitBG.SourceRect.Height));
|
HUDLayoutSettings.BottomRightInfoArea.Height / (float)infoAreaPortraitBG.SourceRect.Height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DrawForeground(SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
if (Character is null || GameMain.IsSingleplayer) { return; }
|
||||||
|
const int million = 1000000;
|
||||||
|
int xfraction = (int)(HUDLayoutSettings.BottomRightInfoArea.Width * 0.2f);
|
||||||
|
int yoffset = GUI.IntScale(6);
|
||||||
|
|
||||||
|
int walletAmount = Character.Wallet.Balance;
|
||||||
|
|
||||||
|
LocalizedString str = walletAmount >= million ? TextManager.Get("crewwallet.balance.toomuchtoshow") : TextManager.FormatCurrency(walletAmount);
|
||||||
|
Vector2 size = GUIStyle.Font.MeasureString(str);
|
||||||
|
int barHeight = GUI.IntScale(18);
|
||||||
|
|
||||||
|
Rectangle barRect = new Rectangle((int)(HUDLayoutSettings.BottomRightInfoArea.X + xfraction / 2.5f), HUDLayoutSettings.BottomRightInfoArea.Bottom - barHeight - yoffset, HUDLayoutSettings.BottomRightInfoArea.Width - xfraction, barHeight);
|
||||||
|
float textScale = Math.Max(0.1f, Math.Min(barRect.Width / size.X, barRect.Height / size.Y)) - 0.01f;
|
||||||
|
|
||||||
|
GUIStyle.WalletPortraitBG.Draw(spriteBatch, barRect, Color.White);
|
||||||
|
|
||||||
|
int iconSize = GUI.IntScale(28);
|
||||||
|
int iconXOffset = iconSize / 2;
|
||||||
|
Rectangle iconRect = new Rectangle(barRect.Right - iconXOffset, barRect.Top - iconSize / 4, iconSize, iconSize);
|
||||||
|
GUIStyle.CrewWalletIconSmall.Draw(spriteBatch, iconRect, Color.White);
|
||||||
|
var (scaledTextSizeX, scaledTextSizeY) = size * textScale;
|
||||||
|
GUIStyle.Font.DrawString(spriteBatch, str, new Vector2(barRect.Right - iconXOffset - scaledTextSizeX - GUI.IntScale(4), barRect.Center.Y - scaledTextSizeY / 2), GUIStyle.TextColorNormal, 0f, Vector2.Zero, textScale, SpriteEffects.None, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 offset, float targetWidth, bool flip = false, bool evaluateDisguise = false)
|
public void DrawPortrait(SpriteBatch spriteBatch, Vector2 screenPos, Vector2 offset, float targetWidth, bool flip = false, bool evaluateDisguise = false)
|
||||||
{
|
{
|
||||||
if (evaluateDisguise && IsDisguised) { return; }
|
if (evaluateDisguise && IsDisguised) { return; }
|
||||||
|
|||||||
@@ -512,23 +512,36 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scrolls the list to the specific element, currently only works when smooth scrolling and PadBottom are enabled.
|
/// Scrolls the list to the specific element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="component"></param>
|
/// <param name="component"></param>
|
||||||
public void ScrollToElement(GUIComponent component)
|
public void ScrollToElement(GUIComponent component, bool playSound = true)
|
||||||
{
|
{
|
||||||
SoundPlayer.PlayUISound(GUISoundType.Click);
|
if (playSound) { SoundPlayer.PlayUISound(GUISoundType.Click); }
|
||||||
List<GUIComponent> children = Content.Children.ToList();
|
List<GUIComponent> children = Content.Children.ToList();
|
||||||
int index = children.IndexOf(component);
|
int index = children.IndexOf(component);
|
||||||
if (index < 0) { return; }
|
if (index < 0) { return; }
|
||||||
|
|
||||||
|
void performScroll(GUIComponent c)
|
||||||
|
{
|
||||||
|
if (SmoothScroll && PadBottom)
|
||||||
|
{
|
||||||
|
scrollToElement = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float diff = isHorizontal ? c.Rect.X - Content.Rect.X : c.Rect.Y - Content.Rect.Y;
|
||||||
|
ScrollBar.BarScroll += diff / TotalSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!Content.Children.Contains(component) || !component.Visible)
|
if (!Content.Children.Contains(component) || !component.Visible)
|
||||||
{
|
{
|
||||||
scrollToElement = null;
|
performScroll(null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scrollToElement = component;
|
performScroll(component);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ namespace Barotrauma
|
|||||||
public readonly static GUISprite UIGlowSolidCircular = new GUISprite("UIGlowSolidCircular");
|
public readonly static GUISprite UIGlowSolidCircular = new GUISprite("UIGlowSolidCircular");
|
||||||
public readonly static GUISprite UIThermalGlow = new GUISprite("UIGlowSolidCircular");
|
public readonly static GUISprite UIThermalGlow = new GUISprite("UIGlowSolidCircular");
|
||||||
public readonly static GUISprite ButtonPulse = new GUISprite("ButtonPulse");
|
public readonly static GUISprite ButtonPulse = new GUISprite("ButtonPulse");
|
||||||
|
public readonly static GUISprite WalletPortraitBG = new GUISprite("WalletPortraitBG");
|
||||||
|
public readonly static GUISprite CrewWalletIconSmall = new GUISprite("CrewWalletIconSmall");
|
||||||
|
|
||||||
public readonly static GUISprite EndRoundButtonPulse = new GUISprite("EndRoundButtonPulse");
|
public readonly static GUISprite EndRoundButtonPulse = new GUISprite("EndRoundButtonPulse");
|
||||||
|
|
||||||
@@ -96,6 +98,11 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly static GUIColor Yellow = new GUIColor("Yellow");
|
public readonly static GUIColor Yellow = new GUIColor("Yellow");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Color to display the name of modded servers in the server list.
|
||||||
|
/// </summary>
|
||||||
|
public readonly static GUIColor ModdedServerColor = new GUIColor("ModdedServerColor");
|
||||||
|
|
||||||
public readonly static GUIColor ColorInventoryEmpty = new GUIColor("ColorInventoryEmpty");
|
public readonly static GUIColor ColorInventoryEmpty = new GUIColor("ColorInventoryEmpty");
|
||||||
public readonly static GUIColor ColorInventoryHalf = new GUIColor("ColorInventoryHalf");
|
public readonly static GUIColor ColorInventoryHalf = new GUIColor("ColorInventoryHalf");
|
||||||
public readonly static GUIColor ColorInventoryFull = new GUIColor("ColorInventoryFull");
|
public readonly static GUIColor ColorInventoryFull = new GUIColor("ColorInventoryFull");
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace Barotrauma
|
|||||||
private GUIImage sellValueChangeArrow;
|
private GUIImage sellValueChangeArrow;
|
||||||
private GUIDropDown sortingDropDown;
|
private GUIDropDown sortingDropDown;
|
||||||
private GUITextBox searchBox;
|
private GUITextBox searchBox;
|
||||||
|
private GUILayoutGroup categoryButtonContainer;
|
||||||
private GUIListBox storeBuyList, storeSellList, storeSellFromSubList;
|
private GUIListBox storeBuyList, storeSellList, storeSellFromSubList;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Can be null when there are no deals at the current location
|
/// Can be null when there are no deals at the current location
|
||||||
@@ -482,7 +483,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Item category buttons ------------------------------------------------
|
// Item category buttons ------------------------------------------------
|
||||||
var categoryButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.08f, 1.0f), storeInventoryContainer.RectTransform))
|
categoryButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.08f, 1.0f), storeInventoryContainer.RectTransform))
|
||||||
{
|
{
|
||||||
RelativeSpacing = 0.02f
|
RelativeSpacing = 0.02f
|
||||||
};
|
};
|
||||||
@@ -765,6 +766,34 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateCategoryButtons()
|
||||||
|
{
|
||||||
|
var tabItems = activeTab switch
|
||||||
|
{
|
||||||
|
StoreTab.Buy => ActiveStore?.Stock,
|
||||||
|
StoreTab.Sell => itemsToSell,
|
||||||
|
StoreTab.SellSub => itemsToSellFromSub,
|
||||||
|
_ => null
|
||||||
|
} ?? Enumerable.Empty<PurchasedItem>();
|
||||||
|
foreach (var button in itemCategoryButtons)
|
||||||
|
{
|
||||||
|
if (!(button.UserData is MapEntityCategory category))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool isButtonEnabled = false;
|
||||||
|
foreach (var item in tabItems)
|
||||||
|
{
|
||||||
|
if (item.ItemPrefab.Category.HasFlag(category))
|
||||||
|
{
|
||||||
|
isButtonEnabled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button.Enabled = isButtonEnabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ChangeStoreTab(StoreTab tab)
|
private void ChangeStoreTab(StoreTab tab)
|
||||||
{
|
{
|
||||||
activeTab = tab;
|
activeTab = tab;
|
||||||
@@ -774,6 +803,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
sortingDropDown.SelectItem(tabSortingMethods[tab]);
|
sortingDropDown.SelectItem(tabSortingMethods[tab]);
|
||||||
relevantBalanceName.Text = IsBuying ? TextManager.Get("campaignstore.balance") : TextManager.Get("campaignstore.storebalance");
|
relevantBalanceName.Text = IsBuying ? TextManager.Get("campaignstore.balance") : TextManager.Get("campaignstore.storebalance");
|
||||||
|
UpdateCategoryButtons();
|
||||||
SetShoppingCrateTotalText();
|
SetShoppingCrateTotalText();
|
||||||
SetClearAllButtonStatus();
|
SetClearAllButtonStatus();
|
||||||
SetConfirmButtonBehavior();
|
SetConfirmButtonBehavior();
|
||||||
@@ -879,7 +909,7 @@ namespace Barotrauma
|
|||||||
prevDailySpecialCount = dailySpecialCount;
|
prevDailySpecialCount = dailySpecialCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasPermissions = HasTabPermissions(StoreTab.Sell);
|
bool hasPermissions = HasTabPermissions(StoreTab.Buy);
|
||||||
var existingItemFrames = new HashSet<GUIComponent>();
|
var existingItemFrames = new HashSet<GUIComponent>();
|
||||||
foreach (PurchasedItem item in ActiveStore.Stock)
|
foreach (PurchasedItem item in ActiveStore.Stock)
|
||||||
{
|
{
|
||||||
@@ -931,7 +961,11 @@ namespace Barotrauma
|
|||||||
removedItemFrames.AddRange(storeDailySpecialsGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
removedItemFrames.AddRange(storeDailySpecialsGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
||||||
}
|
}
|
||||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||||
if (activeTab == StoreTab.Buy) { FilterStoreItems(); }
|
if (activeTab == StoreTab.Buy)
|
||||||
|
{
|
||||||
|
UpdateCategoryButtons();
|
||||||
|
FilterStoreItems();
|
||||||
|
}
|
||||||
SortItems(StoreTab.Buy);
|
SortItems(StoreTab.Buy);
|
||||||
|
|
||||||
storeBuyList.BarScroll = prevBuyListScroll;
|
storeBuyList.BarScroll = prevBuyListScroll;
|
||||||
@@ -1011,7 +1045,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||||
|
|
||||||
if (activeTab == StoreTab.Sell) { FilterStoreItems(); }
|
if (activeTab == StoreTab.Sell)
|
||||||
|
{
|
||||||
|
UpdateCategoryButtons();
|
||||||
|
FilterStoreItems();
|
||||||
|
}
|
||||||
SortItems(StoreTab.Sell);
|
SortItems(StoreTab.Sell);
|
||||||
|
|
||||||
storeSellList.BarScroll = prevSellListScroll;
|
storeSellList.BarScroll = prevSellListScroll;
|
||||||
@@ -1091,7 +1129,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||||
|
|
||||||
if (activeTab == StoreTab.SellSub) { FilterStoreItems(); }
|
if (activeTab == StoreTab.SellSub)
|
||||||
|
{
|
||||||
|
UpdateCategoryButtons();
|
||||||
|
FilterStoreItems();
|
||||||
|
}
|
||||||
SortItems(StoreTab.SellSub);
|
SortItems(StoreTab.SellSub);
|
||||||
|
|
||||||
storeSellFromSubList.BarScroll = prevSellListScroll;
|
storeSellFromSubList.BarScroll = prevSellListScroll;
|
||||||
|
|||||||
@@ -50,19 +50,23 @@ namespace Barotrauma
|
|||||||
private const ushort lowPingThreshold = 100;
|
private const ushort lowPingThreshold = 100;
|
||||||
private const ushort mediumPingThreshold = 200;
|
private const ushort mediumPingThreshold = 200;
|
||||||
|
|
||||||
|
public readonly Client Client;
|
||||||
|
|
||||||
private ushort currentPing;
|
private ushort currentPing;
|
||||||
private readonly Client client;
|
|
||||||
private readonly Character character;
|
private readonly Character character;
|
||||||
private readonly bool hasCharacter;
|
private readonly bool hasCharacter;
|
||||||
private readonly GUITextBlock textBlock;
|
private readonly GUITextBlock textBlock;
|
||||||
private readonly GUIFrame frame;
|
private readonly GUIFrame frame;
|
||||||
|
|
||||||
public LinkedGUI(Client client, GUIFrame frame, bool hasCharacter, GUITextBlock textBlock)
|
private readonly GUIImage permissionIcon;
|
||||||
|
|
||||||
|
public LinkedGUI(Client client, GUIFrame frame, bool hasCharacter, GUITextBlock textBlock, GUIImage permissionIcon)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.Client = client;
|
||||||
this.textBlock = textBlock;
|
this.textBlock = textBlock;
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
this.hasCharacter = hasCharacter;
|
this.hasCharacter = hasCharacter;
|
||||||
|
this.permissionIcon = permissionIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedGUI(Character character, GUIFrame frame, bool hasCharacter, GUITextBlock textBlock)
|
public LinkedGUI(Character character, GUIFrame frame, bool hasCharacter, GUITextBlock textBlock)
|
||||||
@@ -75,33 +79,39 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool HasMultiplayerCharacterChanged()
|
public bool HasMultiplayerCharacterChanged()
|
||||||
{
|
{
|
||||||
if (client == null) return false;
|
if (Client == null) { return false; }
|
||||||
bool characterState = client.Character != null;
|
bool characterState = Client.Character != null;
|
||||||
if (characterState && client.Character.IsDead) characterState = false;
|
if (characterState && Client.Character.IsDead) characterState = false;
|
||||||
return hasCharacter != characterState;
|
return hasCharacter != characterState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasMultiplayerCharacterDied()
|
public bool HasMultiplayerCharacterDied()
|
||||||
{
|
{
|
||||||
if (client == null || !hasCharacter || client.Character == null) return false;
|
if (Client == null || !hasCharacter || Client.Character == null) { return false; }
|
||||||
return client.Character.IsDead;
|
return Client.Character.IsDead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasAICharacterDied()
|
public bool HasAICharacterDied()
|
||||||
{
|
{
|
||||||
if (character == null) return false;
|
if (character == null) { return false; }
|
||||||
return character.IsDead;
|
return character.IsDead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TryPingRefresh()
|
public void TryPingRefresh()
|
||||||
{
|
{
|
||||||
if (client == null) return;
|
if (Client == null) { return; }
|
||||||
if (currentPing == client.Ping) return;
|
if (currentPing == Client.Ping) { return; }
|
||||||
currentPing = client.Ping;
|
currentPing = Client.Ping;
|
||||||
textBlock.Text = currentPing.ToString();
|
textBlock.Text = currentPing.ToString();
|
||||||
textBlock.TextColor = GetPingColor();
|
textBlock.TextColor = GetPingColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TryPermissionIconRefresh(Sprite icon)
|
||||||
|
{
|
||||||
|
if (Client == null || permissionIcon == null) { return; }
|
||||||
|
permissionIcon.Sprite = icon;
|
||||||
|
}
|
||||||
|
|
||||||
private Color GetPingColor()
|
private Color GetPingColor()
|
||||||
{
|
{
|
||||||
if (currentPing < lowPingThreshold)
|
if (currentPing < lowPingThreshold)
|
||||||
@@ -196,6 +206,7 @@ namespace Barotrauma
|
|||||||
for (int i = 0; i < linkedGUIList.Count; i++)
|
for (int i = 0; i < linkedGUIList.Count; i++)
|
||||||
{
|
{
|
||||||
linkedGUIList[i].TryPingRefresh();
|
linkedGUIList[i].TryPingRefresh();
|
||||||
|
linkedGUIList[i].TryPermissionIconRefresh(GetPermissionIcon(linkedGUIList[i].Client));
|
||||||
if (linkedGUIList[i].HasMultiplayerCharacterChanged() || linkedGUIList[i].HasMultiplayerCharacterDied() || linkedGUIList[i].HasAICharacterDied())
|
if (linkedGUIList[i].HasMultiplayerCharacterChanged() || linkedGUIList[i].HasMultiplayerCharacterDied() || linkedGUIList[i].HasAICharacterDied())
|
||||||
{
|
{
|
||||||
RemoveCurrentElements();
|
RemoveCurrentElements();
|
||||||
@@ -549,31 +560,42 @@ namespace Barotrauma
|
|||||||
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
GUITextBlock characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||||
ToolBox.LimitString(character.Info.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
|
ToolBox.LimitString(character.Info.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: character.Info.Job.Prefab.UIColor);
|
||||||
|
|
||||||
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, null));
|
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, textBlock: null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateMultiPlayerListContentHolder(GUILayoutGroup headerFrame)
|
private void CreateMultiPlayerListContentHolder(GUILayoutGroup headerFrame)
|
||||||
{
|
{
|
||||||
|
bool isCampaign = GameMain.GameSession?.Campaign is MultiPlayerCampaign;
|
||||||
GUIButton jobButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("tabmenu.job"), style: "GUIButtonSmallFreeScale");
|
GUIButton jobButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("tabmenu.job"), style: "GUIButtonSmallFreeScale");
|
||||||
GUIButton characterButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("name"), style: "GUIButtonSmallFreeScale");
|
GUIButton characterButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("name"), style: "GUIButtonSmallFreeScale");
|
||||||
GUIButton pingButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("serverlistping"), style: "GUIButtonSmallFreeScale");
|
GUIButton pingButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("serverlistping"), style: "GUIButtonSmallFreeScale");
|
||||||
GUIButton walletButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform), TextManager.Get("crewwallet.wallet"), style: "GUIButtonSmallFreeScale");
|
if (isCampaign)
|
||||||
|
{
|
||||||
|
GUIButton walletButton = new GUIButton(new RectTransform(new Vector2(0f, 1f), headerFrame.RectTransform)
|
||||||
|
{
|
||||||
|
RelativeSize = new Vector2(walletColumnWidthPercentage * sizeMultiplier, 1f)
|
||||||
|
}, TextManager.Get("crewwallet.wallet"), style: "GUIButtonSmallFreeScale")
|
||||||
|
{
|
||||||
|
TextBlock = { Font = GUIStyle.HotkeyFont },
|
||||||
|
CanBeFocused = false,
|
||||||
|
ForceUpperCase = ForceUpperCase.Yes
|
||||||
|
};
|
||||||
|
walletColumnWidth = walletButton.Rect.Width;
|
||||||
|
}
|
||||||
|
|
||||||
sizeMultiplier = (headerFrame.Rect.Width - headerFrame.AbsoluteSpacing * (headerFrame.CountChildren - 1)) / (float)headerFrame.Rect.Width;
|
sizeMultiplier = (headerFrame.Rect.Width - headerFrame.AbsoluteSpacing * (headerFrame.CountChildren - 1)) / (float)headerFrame.Rect.Width;
|
||||||
|
|
||||||
jobButton.RectTransform.RelativeSize = new Vector2(jobColumnWidthPercentage * sizeMultiplier, 1f);
|
jobButton.RectTransform.RelativeSize = new Vector2(jobColumnWidthPercentage * sizeMultiplier, 1f);
|
||||||
characterButton.RectTransform.RelativeSize = new Vector2(characterColumnWidthPercentage * sizeMultiplier, 1f);
|
characterButton.RectTransform.RelativeSize = new Vector2((characterColumnWidthPercentage + (isCampaign ? 0 : walletColumnWidthPercentage)) * sizeMultiplier, 1f);
|
||||||
pingButton.RectTransform.RelativeSize = new Vector2(pingColumnWidthPercentage * sizeMultiplier, 1f);
|
pingButton.RectTransform.RelativeSize = new Vector2(pingColumnWidthPercentage * sizeMultiplier, 1f);
|
||||||
walletButton.RectTransform.RelativeSize = new Vector2(walletColumnWidthPercentage * sizeMultiplier, 1f);
|
|
||||||
|
|
||||||
jobButton.TextBlock.Font = characterButton.TextBlock.Font = pingButton.TextBlock.Font = walletButton.TextBlock.Font = GUIStyle.HotkeyFont;
|
jobButton.TextBlock.Font = characterButton.TextBlock.Font = pingButton.TextBlock.Font = GUIStyle.HotkeyFont;
|
||||||
jobButton.CanBeFocused = characterButton.CanBeFocused = pingButton.CanBeFocused = walletButton.CanBeFocused = false;
|
jobButton.CanBeFocused = characterButton.CanBeFocused = pingButton.CanBeFocused = false;
|
||||||
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = pingButton.ForceUpperCase = walletButton.ForceUpperCase = ForceUpperCase.Yes;
|
jobButton.TextBlock.ForceUpperCase = characterButton.TextBlock.ForceUpperCase = pingButton.ForceUpperCase = ForceUpperCase.Yes;
|
||||||
|
|
||||||
jobColumnWidth = jobButton.Rect.Width;
|
jobColumnWidth = jobButton.Rect.Width;
|
||||||
characterColumnWidth = characterButton.Rect.Width;
|
characterColumnWidth = characterButton.Rect.Width;
|
||||||
pingColumnWidth = pingButton.Rect.Width;
|
pingColumnWidth = pingButton.Rect.Width;
|
||||||
walletColumnWidth = walletButton.Rect.Width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateMultiPlayerList(bool refresh)
|
private void CreateMultiPlayerList(bool refresh)
|
||||||
@@ -634,8 +656,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
CreateNameWithPermissionIcon(client, paddedFrame);
|
CreateNameWithPermissionIcon(client, paddedFrame, out GUIImage permissionIcon);
|
||||||
linkedGUIList.Add(new LinkedGUI(client, frame, true, new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), client.Ping.ToString(), textAlignment: Alignment.Center)));
|
linkedGUIList.Add(new LinkedGUI(client, frame, true,
|
||||||
|
new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), client.Ping.ToString(), textAlignment: Alignment.Center),
|
||||||
|
permissionIcon));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -644,11 +668,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (character is AICharacter)
|
if (character is AICharacter)
|
||||||
{
|
{
|
||||||
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead, new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), TextManager.Get("tabmenu.bot"), textAlignment: Alignment.Center) { ForceUpperCase = ForceUpperCase.Yes }));
|
linkedGUIList.Add(new LinkedGUI(character, frame, !character.IsDead,
|
||||||
|
new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), TextManager.Get("tabmenu.bot"), textAlignment: Alignment.Center) { ForceUpperCase = ForceUpperCase.Yes }));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linkedGUIList.Add(new LinkedGUI(client: null, frame, true, null));
|
linkedGUIList.Add(new LinkedGUI(client: null, frame, true, textBlock: null, permissionIcon: null));
|
||||||
|
|
||||||
new GUICustomComponent(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform, Anchor.Center), onDraw: (sb, component) => DrawDisconnectedIcon(sb, component.Rect))
|
new GUICustomComponent(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform, Anchor.Center), onDraw: (sb, component) => DrawDisconnectedIcon(sb, component.Rect))
|
||||||
{
|
{
|
||||||
@@ -686,12 +711,15 @@ namespace Barotrauma
|
|||||||
SelectedColor = Color.White
|
SelectedColor = Color.White
|
||||||
};
|
};
|
||||||
|
|
||||||
CreateNameWithPermissionIcon(client, paddedFrame);
|
CreateNameWithPermissionIcon(client, paddedFrame, out GUIImage permissionIcon);
|
||||||
|
linkedGUIList.Add(new LinkedGUI(client, frame, false,
|
||||||
|
new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), client.Ping.ToString(), textAlignment: Alignment.Center),
|
||||||
|
permissionIcon));
|
||||||
|
|
||||||
if (client.Character is { } character)
|
if (client.Character is { } character)
|
||||||
{
|
{
|
||||||
CreateWalletCrewFrame(character, paddedFrame);
|
CreateWalletCrewFrame(character, paddedFrame);
|
||||||
}
|
}
|
||||||
linkedGUIList.Add(new LinkedGUI(client, frame, false, new GUITextBlock(new RectTransform(new Point(pingColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform), client.Ping.ToString(), textAlignment: Alignment.Center)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetTeamIndex(Client client)
|
private int GetTeamIndex(Client client)
|
||||||
@@ -729,21 +757,47 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void CreateWalletCrewFrame(Character character, GUILayoutGroup paddedFrame)
|
private void CreateWalletCrewFrame(Character character, GUILayoutGroup paddedFrame)
|
||||||
{
|
{
|
||||||
|
if (!(GameMain.GameSession?.Campaign is MultiPlayerCampaign)) { return; }
|
||||||
|
|
||||||
GUILayoutGroup walletLayout = new GUILayoutGroup(new RectTransform(new Point(walletColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform, Anchor.Center), childAnchor: Anchor.Center)
|
GUILayoutGroup walletLayout = new GUILayoutGroup(new RectTransform(new Point(walletColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform, Anchor.Center), childAnchor: Anchor.Center)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (character.IsBot) { return; }
|
|
||||||
|
|
||||||
GUILayoutGroup paddedLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1f), walletLayout.RectTransform, Anchor.Center), isHorizontal: true)
|
GUILayoutGroup paddedLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1f), walletLayout.RectTransform, Anchor.Center), isHorizontal: true)
|
||||||
{
|
{
|
||||||
Stretch = true
|
Stretch = true
|
||||||
};
|
};
|
||||||
|
|
||||||
GUIImage icon = new GUIImage(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "StoreTradingIcon", scaleToFit: true);
|
if (character.IsBot) { return; }
|
||||||
GUITextBlock walletBlock = new GUITextBlock(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform), string.Empty, textAlignment: Alignment.Right, font: GUIStyle.SubHeadingFont);
|
|
||||||
SetWalletText(walletBlock, character.Wallet);
|
Sprite walletSprite = GUIStyle.CrewWalletIconSmall.Value.Sprite;
|
||||||
|
|
||||||
|
GUIImage icon = new GUIImage(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), walletSprite, scaleToFit: true);
|
||||||
|
GUITextBlock walletBlock = new GUITextBlock(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform), string.Empty, textAlignment: Alignment.Right, font: GUIStyle.Font)
|
||||||
|
{
|
||||||
|
AutoScaleHorizontal = true,
|
||||||
|
Padding = Vector4.Zero
|
||||||
|
};
|
||||||
|
|
||||||
|
GUIImage largeIcon = new GUIImage(new RectTransform(Vector2.One, paddedLayoutGroup.RectTransform), walletSprite, scaleToFit: true)
|
||||||
|
{
|
||||||
|
IgnoreLayoutGroups = true,
|
||||||
|
Visible = false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (character.IsBot)
|
||||||
|
{
|
||||||
|
largeIcon.Visible = true;
|
||||||
|
icon.Visible = false;
|
||||||
|
walletBlock.Visible = false;
|
||||||
|
largeIcon.Enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
walletLayout.Recalculate();
|
||||||
|
paddedLayoutGroup.Recalculate();
|
||||||
|
SetWalletText(walletBlock, character.Wallet, icon, largeIcon);
|
||||||
|
|
||||||
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign campaign)
|
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign campaign)
|
||||||
{
|
{
|
||||||
@@ -751,47 +805,56 @@ namespace Barotrauma
|
|||||||
campaign.OnMoneyChanged.RegisterOverwriteExisting(eventIdentifier, e =>
|
campaign.OnMoneyChanged.RegisterOverwriteExisting(eventIdentifier, e =>
|
||||||
{
|
{
|
||||||
if (!(e.Owner is Some<Character> { Value: var owner }) || owner != character) { return; }
|
if (!(e.Owner is Some<Character> { Value: var owner }) || owner != character) { return; }
|
||||||
SetWalletText(walletBlock, e.Wallet);
|
SetWalletText(walletBlock, e.Wallet, icon, largeIcon);
|
||||||
});
|
});
|
||||||
registeredEvents.Add(eventIdentifier);
|
registeredEvents.Add(eventIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetWalletText(GUITextBlock block, Wallet wallet)
|
static void SetWalletText(GUITextBlock block, Wallet wallet, GUIImage icon, GUIImage largeIcon)
|
||||||
{
|
{
|
||||||
|
const int million = 1000000,
|
||||||
|
tooSmallPixelTreshold = 50; // 50 pixels is just not enough to see any meaningful info
|
||||||
|
|
||||||
block.Text = TextManager.FormatCurrency(wallet.Balance);
|
block.Text = TextManager.FormatCurrency(wallet.Balance);
|
||||||
block.ToolTip = string.Empty;
|
block.ToolTip = string.Empty;
|
||||||
if (block.TextSize.X + block.Padding.X + block.Padding.Z > block.Rect.Width)
|
|
||||||
|
if (wallet.Balance >= million)
|
||||||
{
|
{
|
||||||
block.ToolTip = block.Text;
|
|
||||||
block.Text = TextManager.Get("crewwallet.balance.toomuchtoshow");
|
block.Text = TextManager.Get("crewwallet.balance.toomuchtoshow");
|
||||||
|
block.ToolTip = block.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
largeIcon.Visible = false;
|
||||||
|
icon.Visible = true;
|
||||||
|
block.Visible = true;
|
||||||
|
|
||||||
|
if (tooSmallPixelTreshold > block.Rect.Width)
|
||||||
|
{
|
||||||
|
largeIcon.Visible = true;
|
||||||
|
icon.Visible = false;
|
||||||
|
block.Visible = false;
|
||||||
|
largeIcon.ToolTip = block.Text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateNameWithPermissionIcon(Client client, GUILayoutGroup paddedFrame)
|
private void CreateNameWithPermissionIcon(Client client, GUILayoutGroup paddedFrame, out GUIImage permissionIcon)
|
||||||
{
|
{
|
||||||
GUITextBlock characterNameBlock;
|
GUITextBlock characterNameBlock;
|
||||||
Sprite permissionIcon = GetPermissionIcon(client);
|
Sprite permissionIconSprite = GetPermissionIcon(client);
|
||||||
JobPrefab prefab = client.Character?.Info?.Job?.Prefab;
|
JobPrefab prefab = client.Character?.Info?.Job?.Prefab;
|
||||||
Color nameColor = prefab != null ? prefab.UIColor : Color.White;
|
Color nameColor = prefab != null ? prefab.UIColor : Color.White;
|
||||||
|
|
||||||
if (permissionIcon != null)
|
Point iconSize = new Point((int)(paddedFrame.Rect.Height * 0.8f));
|
||||||
{
|
float characterNameWidthAdjustment = (iconSize.X + paddedFrame.AbsoluteSpacing) / characterColumnWidth;
|
||||||
Point iconSize = permissionIcon.SourceRect.Size;
|
|
||||||
float characterNameWidthAdjustment = (iconSize.X + paddedFrame.AbsoluteSpacing) / characterColumnWidth;
|
|
||||||
|
|
||||||
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
||||||
ToolBox.LimitString(client.Name, GUIStyle.Font, (int)(characterColumnWidth - paddedFrame.Rect.Width * characterNameWidthAdjustment)), textAlignment: Alignment.Center, textColor: nameColor);
|
ToolBox.LimitString(client.Name, GUIStyle.Font, (int)(characterColumnWidth - paddedFrame.Rect.Width * characterNameWidthAdjustment)), textAlignment: Alignment.Center, textColor: nameColor);
|
||||||
|
|
||||||
|
float iconWidth = iconSize.X / (float)characterColumnWidth;
|
||||||
|
int xOffset = (int)(jobColumnWidth + characterNameBlock.TextPos.X - GUIStyle.Font.MeasureString(characterNameBlock.Text).X / 2f - paddedFrame.AbsoluteSpacing - iconWidth * paddedFrame.Rect.Width);
|
||||||
|
permissionIcon = new GUIImage(new RectTransform(new Vector2(iconWidth, 1f), paddedFrame.RectTransform) { AbsoluteOffset = new Point(xOffset + 2, 0) }, permissionIconSprite) { IgnoreLayoutGroups = true };
|
||||||
|
|
||||||
float iconWidth = iconSize.X / (float)characterColumnWidth;
|
|
||||||
int xOffset = (int)(jobColumnWidth + characterNameBlock.TextPos.X - GUIStyle.Font.MeasureString(characterNameBlock.Text).X / 2f - paddedFrame.AbsoluteSpacing - iconWidth * paddedFrame.Rect.Width);
|
|
||||||
new GUIImage(new RectTransform(new Vector2(iconWidth, 1f), paddedFrame.RectTransform) { AbsoluteOffset = new Point(xOffset + 2, 0) }, permissionIcon) { IgnoreLayoutGroups = true };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
characterNameBlock = new GUITextBlock(new RectTransform(new Point(characterColumnWidth, paddedFrame.Rect.Height), paddedFrame.RectTransform),
|
|
||||||
ToolBox.LimitString(client.Name, GUIStyle.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: nameColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client.Character != null && client.Character.IsDead)
|
if (client.Character != null && client.Character.IsDead)
|
||||||
{
|
{
|
||||||
@@ -801,7 +864,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private Sprite GetPermissionIcon(Client client)
|
private Sprite GetPermissionIcon(Client client)
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember == null || client == null || !client.HasPermissions) return null;
|
if (GameMain.NetworkMember == null || client == null || !client.HasPermissions) { return null; }
|
||||||
|
|
||||||
if (client.IsOwner) // Owner cannot be kicked
|
if (client.IsOwner) // Owner cannot be kicked
|
||||||
{
|
{
|
||||||
@@ -898,7 +961,7 @@ namespace Barotrauma
|
|||||||
GUILayoutGroup walletLayout = new GUILayoutGroup(new RectTransform(ToolBox.PaddingSizeParentRelative(walletFrame.RectTransform, 0.9f), walletFrame.RectTransform, anchor: Anchor.Center));
|
GUILayoutGroup walletLayout = new GUILayoutGroup(new RectTransform(ToolBox.PaddingSizeParentRelative(walletFrame.RectTransform, 0.9f), walletFrame.RectTransform, anchor: Anchor.Center));
|
||||||
|
|
||||||
GUILayoutGroup headerLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.33f), walletLayout.RectTransform), isHorizontal: true);
|
GUILayoutGroup headerLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.33f), walletLayout.RectTransform), isHorizontal: true);
|
||||||
GUIImage icon = new GUIImage(new RectTransform(Vector2.One, headerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "StoreTradingIcon", scaleToFit: true);
|
GUIImage icon = new GUIImage(new RectTransform(Vector2.One, headerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "CrewWalletIconLarge", scaleToFit: true);
|
||||||
float relativeX = icon.RectTransform.NonScaledSize.X / (float)icon.Parent.RectTransform.NonScaledSize.X;
|
float relativeX = icon.RectTransform.NonScaledSize.X / (float)icon.Parent.RectTransform.NonScaledSize.X;
|
||||||
GUILayoutGroup headerTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - relativeX, 1f), headerLayout.RectTransform), isHorizontal: true) { Stretch = true };
|
GUILayoutGroup headerTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - relativeX, 1f), headerLayout.RectTransform), isHorizontal: true) { Stretch = true };
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), TextManager.Get("crewwallet.wallet"), font: GUIStyle.LargeFont);
|
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), TextManager.Get("crewwallet.wallet"), font: GUIStyle.LargeFont);
|
||||||
@@ -950,7 +1013,7 @@ namespace Barotrauma
|
|||||||
GUITextBlock rightBalance = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), rightLayout.RectTransform), string.Empty, textAlignment: Alignment.Right) { TextColor = GUIStyle.Red };
|
GUITextBlock rightBalance = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), rightLayout.RectTransform), string.Empty, textAlignment: Alignment.Right) { TextColor = GUIStyle.Red };
|
||||||
GUILayoutGroup centerLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), mainLayout.RectTransform, Anchor.Center), childAnchor: Anchor.Center) { IgnoreLayoutGroups = true };
|
GUILayoutGroup centerLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), mainLayout.RectTransform, Anchor.Center), childAnchor: Anchor.Center) { IgnoreLayoutGroups = true };
|
||||||
new GUIFrame(new RectTransform(new Vector2(0f, 1f), centerLayout.RectTransform, Anchor.Center), style: "VerticalLine") { IgnoreLayoutGroups = true };
|
new GUIFrame(new RectTransform(new Vector2(0f, 1f), centerLayout.RectTransform, Anchor.Center), style: "VerticalLine") { IgnoreLayoutGroups = true };
|
||||||
GUIButton centerButton = new GUIButton(new RectTransform(new Vector2(0.6f), centerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight, anchor: Anchor.Center), style: "GUIButtonTransferArrow");
|
GUIButton centerButton = new GUIButton(new RectTransform(new Vector2(1f), centerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight, anchor: Anchor.Center), style: "GUIButtonTransferArrow");
|
||||||
|
|
||||||
GUILayoutGroup inputLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.25f), paddedTransferMenuLayout.RectTransform), childAnchor: Anchor.Center);
|
GUILayoutGroup inputLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.25f), paddedTransferMenuLayout.RectTransform), childAnchor: Anchor.Center);
|
||||||
GUINumberInput transferAmountInput = new GUINumberInput(new RectTransform(new Vector2(0.5f, 1f), inputLayout.RectTransform), GUINumberInput.NumberType.Int, hidePlusMinusButtons: true)
|
GUINumberInput transferAmountInput = new GUINumberInput(new RectTransform(new Vector2(0.5f, 1f), inputLayout.RectTransform), GUINumberInput.NumberType.Int, hidePlusMinusButtons: true)
|
||||||
|
|||||||
@@ -477,6 +477,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
DebugConsole.Init();
|
DebugConsole.Init();
|
||||||
|
|
||||||
|
ContentPackageManager.LogEnabledRegularPackageErrors();
|
||||||
|
|
||||||
#if !DEBUG && !OSX
|
#if !DEBUG && !OSX
|
||||||
GameAnalyticsManager.InitIfConsented();
|
GameAnalyticsManager.InitIfConsented();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override bool ShouldDrawHUD(Character character)
|
public override bool ShouldDrawHUD(Character character)
|
||||||
{
|
{
|
||||||
|
if (item.HiddenInGame) { return false; }
|
||||||
if (!HasRequiredItems(character, false) || character.SelectedConstruction != item) { return false; }
|
if (!HasRequiredItems(character, false) || character.SelectedConstruction != item) { return false; }
|
||||||
if (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition) { return true; }
|
if (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition) { return true; }
|
||||||
|
|
||||||
@@ -222,6 +223,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
partial void UpdateProjSpecific(float deltaTime)
|
partial void UpdateProjSpecific(float deltaTime)
|
||||||
{
|
{
|
||||||
|
if (item.HiddenInGame) { return; }
|
||||||
if (FakeBrokenTimer > 0.0f)
|
if (FakeBrokenTimer > 0.0f)
|
||||||
{
|
{
|
||||||
item.FakeBroken = true;
|
item.FakeBroken = true;
|
||||||
|
|||||||
@@ -358,9 +358,9 @@ namespace Barotrauma
|
|||||||
WorldRect.Width, WorldRect.Height);
|
WorldRect.Width, WorldRect.Height);
|
||||||
|
|
||||||
GUI.DrawLine(spriteBatch,
|
GUI.DrawLine(spriteBatch,
|
||||||
new Vector2(currentHullRect.X, -currentHullRect.Y),
|
new Vector2(currentHullRect.X, -currentHullRect.Y),
|
||||||
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
|
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
|
||||||
GUIStyle.Green, width: 2);
|
GUIStyle.Green, width: 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -378,7 +378,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (section.ColorStrength < 0.01f || section.Color.A < 1) { continue; }
|
if (section.ColorStrength < 0.01f || section.Color.A < 1) { continue; }
|
||||||
|
|
||||||
if (DecalManager.GrimeSprites.None())
|
if (section.GrimeSprite == null)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch,
|
GUI.DrawRectangle(spriteBatch,
|
||||||
new Vector2(drawOffset.X + rect.X + section.Rect.X, -(drawOffset.Y + rect.Y + section.Rect.Y)),
|
new Vector2(drawOffset.X + rect.X + section.Rect.X, -(drawOffset.Y + rect.Y + section.Rect.Y)),
|
||||||
@@ -389,8 +389,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Vector2 sectionPos = new Vector2(drawPos.X + section.Rect.Location.X, -(drawPos.Y + section.Rect.Location.Y));
|
Vector2 sectionPos = new Vector2(drawPos.X + section.Rect.Location.X, -(drawPos.Y + section.Rect.Location.Y));
|
||||||
Vector2 randomOffset = new Vector2(section.Noise.X - 0.5f, section.Noise.Y - 0.5f) * 15.0f;
|
Vector2 randomOffset = new Vector2(section.Noise.X - 0.5f, section.Noise.Y - 0.5f) * 15.0f;
|
||||||
var sprite = DecalManager.GrimeSprites[$"{nameof(GrimeSprite)}{i % DecalManager.GrimeSpriteCount}"].Sprite;
|
section.GrimeSprite.Draw(spriteBatch, sectionPos + randomOffset, section.GetStrengthAdjustedColor(), scale: 1.25f);
|
||||||
sprite.Draw(spriteBatch, sectionPos + randomOffset, section.GetStrengthAdjustedColor(), scale: 1.25f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
Vector2 center = new Vector2((minX + maxX) / 2.0f, (minY + maxY) / 2.0f);
|
Vector2 center = new Vector2((minX + maxX) / 2.0f, (minY + maxY) / 2.0f);
|
||||||
if (Submarine.MainSub != null) { center -= Submarine.MainSub.HiddenSubPosition; }
|
if (Submarine.MainSub != null) { center -= Submarine.MainSub.HiddenSubPosition; }
|
||||||
center.X -= center.X % Submarine.GridSize.X;
|
center.X -= MathUtils.RoundTowardsClosest(center.X, Submarine.GridSize.X);
|
||||||
center.Y -= center.Y % Submarine.GridSize.Y;
|
center.Y -= MathUtils.RoundTowardsClosest(center.Y, Submarine.GridSize.Y);
|
||||||
|
|
||||||
MapEntity.SelectedList.Clear();
|
MapEntity.SelectedList.Clear();
|
||||||
assemblyEntities.ForEach(e => MapEntity.AddSelection(e));
|
assemblyEntities.ForEach(e => MapEntity.AddSelection(e));
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace Barotrauma
|
|||||||
Stretch = true,
|
Stretch = true,
|
||||||
RelativeSpacing = 0.01f
|
RelativeSpacing = 0.01f
|
||||||
};
|
};
|
||||||
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"))
|
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"), style: "GUIButtonSmall")
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("MirrorEntityXToolTip"),
|
ToolTip = TextManager.Get("MirrorEntityXToolTip"),
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
@@ -156,7 +156,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"))
|
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityY"), style: "GUIButtonSmall")
|
||||||
{
|
{
|
||||||
ToolTip = TextManager.Get("MirrorEntityYToolTip"),
|
ToolTip = TextManager.Get("MirrorEntityYToolTip"),
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
@@ -169,7 +169,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"))
|
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ReloadSprite"), style: "GUIButtonSmall")
|
||||||
{
|
{
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
{
|
{
|
||||||
@@ -178,7 +178,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ResetToPrefab"))
|
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("ResetToPrefab"), style: "GUIButtonSmall")
|
||||||
{
|
{
|
||||||
OnClicked = (button, data) =>
|
OnClicked = (button, data) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -186,9 +186,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (predicate != null)
|
if (predicate != null)
|
||||||
{
|
{
|
||||||
if (!predicate(e)) continue;
|
if (!predicate(e)) { continue; }
|
||||||
}
|
}
|
||||||
|
|
||||||
hull.DrawSectionColors(spriteBatch);
|
hull.DrawSectionColors(spriteBatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), spawnTypeContainer.RectTransform), TextManager.Get("SpawnType"));
|
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), spawnTypeContainer.RectTransform), TextManager.Get("SpawnType"));
|
||||||
|
|
||||||
var button = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), spawnTypeContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton")
|
var button = new GUIButton(new RectTransform(Vector2.One, spawnTypeContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton")
|
||||||
{
|
{
|
||||||
UserData = -1,
|
UserData = -1,
|
||||||
OnClicked = ChangeSpawnType
|
OnClicked = ChangeSpawnType
|
||||||
@@ -308,7 +308,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
UserData = "spawntypetext"
|
UserData = "spawntypetext"
|
||||||
};
|
};
|
||||||
button = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), spawnTypeContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton")
|
button = new GUIButton(new RectTransform(Vector2.One, spawnTypeContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton")
|
||||||
{
|
{
|
||||||
UserData = 1,
|
UserData = 1,
|
||||||
OnClicked = ChangeSpawnType
|
OnClicked = ChangeSpawnType
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Permissions.HasFlag(permission)) Permissions |= permission;
|
if (!Permissions.HasFlag(permission)) { Permissions |= permission; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemovePermission(ClientPermissions permission)
|
public void RemovePermission(ClientPermissions permission)
|
||||||
@@ -117,7 +117,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Permissions.HasFlag(permission)) Permissions &= ~permission;
|
if (Permissions.HasFlag(permission)) { Permissions &= ~permission; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasPermission(ClientPermissions permission)
|
public bool HasPermission(ClientPermissions permission)
|
||||||
|
|||||||
@@ -51,6 +51,17 @@ namespace Barotrauma.Networking
|
|||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DateTime LastOffsetAckTime
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordOffsetAckTime()
|
||||||
|
{
|
||||||
|
LastOffsetAckTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
public float BytesPerSecond
|
public float BytesPerSecond
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -91,6 +102,8 @@ namespace Barotrauma.Networking
|
|||||||
Connection = connection;
|
Connection = connection;
|
||||||
|
|
||||||
Status = FileTransferStatus.NotStarted;
|
Status = FileTransferStatus.NotStarted;
|
||||||
|
|
||||||
|
LastOffsetAckTime = DateTime.Now - new TimeSpan(days: 0, hours: 0, minutes: 5, seconds: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenStream()
|
public void OpenStream()
|
||||||
@@ -214,11 +227,11 @@ namespace Barotrauma.Networking
|
|||||||
fileName != existingTransfer.FileName)
|
fileName != existingTransfer.FileName)
|
||||||
{
|
{
|
||||||
GameMain.Client.CancelFileTransfer(transferId);
|
GameMain.Client.CancelFileTransfer(transferId);
|
||||||
DebugConsole.ThrowError("File transfer error: file transfer initiated with an ID that's already in use");
|
DebugConsole.AddWarning("File transfer error: file transfer initiated with an ID that's already in use");
|
||||||
}
|
}
|
||||||
else //resend acknowledgement packet
|
else //resend acknowledgement packet
|
||||||
{
|
{
|
||||||
GameMain.Client.UpdateFileTransfer(transferId, existingTransfer.Received, existingTransfer.LastSeen);
|
GameMain.Client.UpdateFileTransfer(existingTransfer, existingTransfer.Received, existingTransfer.LastSeen);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -285,7 +298,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
activeTransfers.Add(newTransfer);
|
activeTransfers.Add(newTransfer);
|
||||||
|
|
||||||
GameMain.Client.UpdateFileTransfer(transferId, 0, 0); //send acknowledgement packet
|
GameMain.Client.UpdateFileTransfer(newTransfer, 0, 0); //send acknowledgement packet
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case (byte)FileTransferMessageType.TransferOnSameMachine:
|
case (byte)FileTransferMessageType.TransferOnSameMachine:
|
||||||
@@ -333,7 +346,7 @@ namespace Barotrauma.Networking
|
|||||||
if (!finishedTransfers.Any(t => t.transferId == transferId))
|
if (!finishedTransfers.Any(t => t.transferId == transferId))
|
||||||
{
|
{
|
||||||
GameMain.Client.CancelFileTransfer(transferId);
|
GameMain.Client.CancelFileTransfer(transferId);
|
||||||
DebugConsole.ThrowError("File transfer error: received data without a transfer initiation message");
|
DebugConsole.AddWarning("File transfer error: received data without a transfer initiation message");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -344,7 +357,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
activeTransfer.LastSeen = Math.Max(offset, activeTransfer.LastSeen);
|
activeTransfer.LastSeen = Math.Max(offset, activeTransfer.LastSeen);
|
||||||
DebugConsole.Log($"Received {bytesToRead} bytes of the file {activeTransfer.FileName} (ignoring: offset {offset}, waiting for {activeTransfer.Received})");
|
DebugConsole.Log($"Received {bytesToRead} bytes of the file {activeTransfer.FileName} (ignoring: offset {offset}, waiting for {activeTransfer.Received})");
|
||||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received, activeTransfer.LastSeen);
|
GameMain.Client.UpdateFileTransfer(activeTransfer, activeTransfer.Received, activeTransfer.LastSeen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
activeTransfer.LastSeen = offset;
|
activeTransfer.LastSeen = offset;
|
||||||
@@ -375,7 +388,7 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received, activeTransfer.LastSeen, reliable: activeTransfer.Status == FileTransferStatus.Finished);
|
GameMain.Client.UpdateFileTransfer(activeTransfer, activeTransfer.Received, activeTransfer.LastSeen, reliable: activeTransfer.Status == FileTransferStatus.Finished);
|
||||||
if (activeTransfer.Status == FileTransferStatus.Finished)
|
if (activeTransfer.Status == FileTransferStatus.Finished)
|
||||||
{
|
{
|
||||||
activeTransfer.Dispose();
|
activeTransfer.Dispose();
|
||||||
|
|||||||
@@ -1947,7 +1947,6 @@ namespace Barotrauma.Networking
|
|||||||
existingClient.Character = null;
|
existingClient.Character = null;
|
||||||
existingClient.Karma = tc.Karma;
|
existingClient.Karma = tc.Karma;
|
||||||
existingClient.Muted = tc.Muted;
|
existingClient.Muted = tc.Muted;
|
||||||
existingClient.HasPermissions = tc.HasPermissions;
|
|
||||||
existingClient.InGame = tc.InGame;
|
existingClient.InGame = tc.InGame;
|
||||||
existingClient.IsOwner = tc.IsOwner;
|
existingClient.IsOwner = tc.IsOwner;
|
||||||
existingClient.AllowKicking = tc.AllowKicking;
|
existingClient.AllowKicking = tc.AllowKicking;
|
||||||
@@ -2493,12 +2492,18 @@ namespace Barotrauma.Networking
|
|||||||
CancelFileTransfer(transfer.ID);
|
CancelFileTransfer(transfer.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateFileTransfer(int id, int expecting, int lastSeen, bool reliable = false)
|
public void UpdateFileTransfer(FileReceiver.FileTransferIn transfer, int expecting, int lastSeen, bool reliable = false)
|
||||||
{
|
{
|
||||||
|
if (!reliable && (DateTime.Now - transfer.LastOffsetAckTime).TotalSeconds < 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
transfer.RecordOffsetAckTime();
|
||||||
|
|
||||||
IWriteMessage msg = new WriteOnlyMessage();
|
IWriteMessage msg = new WriteOnlyMessage();
|
||||||
msg.Write((byte)ClientPacketHeader.FILE_REQUEST);
|
msg.Write((byte)ClientPacketHeader.FILE_REQUEST);
|
||||||
msg.Write((byte)FileTransferMessageType.Data);
|
msg.Write((byte)FileTransferMessageType.Data);
|
||||||
msg.Write((byte)id);
|
msg.Write((byte)transfer.ID);
|
||||||
msg.Write(expecting);
|
msg.Write(expecting);
|
||||||
msg.Write(lastSeen);
|
msg.Write(lastSeen);
|
||||||
clientPeer.Send(msg, reliable ? DeliveryMethod.Reliable : DeliveryMethod.Unreliable);
|
clientPeer.Send(msg, reliable ? DeliveryMethod.Reliable : DeliveryMethod.Unreliable);
|
||||||
@@ -2784,7 +2789,9 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void ShowSubmarineChangeVoteInterface(Client starter, SubmarineInfo info, VoteType type, float timeOut)
|
public void ShowSubmarineChangeVoteInterface(Client starter, SubmarineInfo info, VoteType type, float timeOut)
|
||||||
{
|
{
|
||||||
if (info == null || votingInterface != null) { return; }
|
if (info == null) { return; }
|
||||||
|
if (votingInterface != null && votingInterface.VoteRunning) { return; }
|
||||||
|
votingInterface?.Remove();
|
||||||
votingInterface = VotingInterface.CreateSubmarineVotingInterface(starter, info, type, timeOut);
|
votingInterface = VotingInterface.CreateSubmarineVotingInterface(starter, info, type, timeOut);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@@ -2792,12 +2799,13 @@ namespace Barotrauma.Networking
|
|||||||
#region Money Transfer Voting
|
#region Money Transfer Voting
|
||||||
public void ShowMoneyTransferVoteInterface(Client starter, Client from, int amount, Client to, float timeOut)
|
public void ShowMoneyTransferVoteInterface(Client starter, Client from, int amount, Client to, float timeOut)
|
||||||
{
|
{
|
||||||
if (votingInterface != null) { return; }
|
if (votingInterface != null && votingInterface.VoteRunning) { return; }
|
||||||
if (from == null && to == null)
|
if (from == null && to == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Tried to initiate a vote for transferring from null to null!");
|
DebugConsole.ThrowError("Tried to initiate a vote for transferring from null to null!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
votingInterface?.Remove();
|
||||||
votingInterface = VotingInterface.CreateMoneyTransferVotingInterface(starter, from, to, amount, timeOut);
|
votingInterface = VotingInterface.CreateMoneyTransferVotingInterface(starter, from, to, amount, timeOut);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -79,24 +79,6 @@ namespace Barotrauma.Networking
|
|||||||
private set;
|
private set;
|
||||||
} = new List<ulong>();
|
} = new List<ulong>();
|
||||||
|
|
||||||
public bool ContentPackagesMatch()
|
|
||||||
{
|
|
||||||
//make sure we have all the packages the server requires
|
|
||||||
if (ContentPackageHashes.Count != ContentPackageWorkshopIds.Count) { return false; }
|
|
||||||
for (int i = 0; i < ContentPackageWorkshopIds.Count; i++)
|
|
||||||
{
|
|
||||||
string hash = ContentPackageHashes[i];
|
|
||||||
UInt64 id = ContentPackageWorkshopIds[i];
|
|
||||||
if (!GameMain.ServerListScreen.ContentPackagesByHash.ContainsKey(hash))
|
|
||||||
{
|
|
||||||
if (GameMain.ServerListScreen.ContentPackagesByWorkshopId.ContainsKey(id)) { return false; }
|
|
||||||
if (id == 0) { return false; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreatePreviewWindow(GUIFrame frame)
|
public void CreatePreviewWindow(GUIFrame frame)
|
||||||
{
|
{
|
||||||
if (frame == null) { return; }
|
if (frame == null) { return; }
|
||||||
@@ -105,7 +87,8 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform), ServerName, font: GUIStyle.LargeFont)
|
var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform), ServerName, font: GUIStyle.LargeFont)
|
||||||
{
|
{
|
||||||
ToolTip = ServerName
|
ToolTip = ServerName,
|
||||||
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
title.Text = ToolBox.LimitString(title.Text, title.Font, (int)(title.Rect.Width * 0.85f));
|
title.Text = ToolBox.LimitString(title.Text, title.Font, (int)(title.Rect.Width * 0.85f));
|
||||||
|
|
||||||
@@ -130,7 +113,11 @@ namespace Barotrauma.Networking
|
|||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
||||||
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion));
|
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"),
|
||||||
|
string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion))
|
||||||
|
{
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
|
||||||
bool hidePlaystyleBanner = !PlayStyle.HasValue;
|
bool hidePlaystyleBanner = !PlayStyle.HasValue;
|
||||||
if (!hidePlaystyleBanner)
|
if (!hidePlaystyleBanner)
|
||||||
@@ -141,15 +128,23 @@ namespace Barotrauma.Networking
|
|||||||
var playStyleBanner = new GUIImage(new RectTransform(new Point(frame.Rect.Width, (int)(frame.Rect.Width / playStyleBannerAspectRatio)), frame.RectTransform),
|
var playStyleBanner = new GUIImage(new RectTransform(new Point(frame.Rect.Width, (int)(frame.Rect.Width / playStyleBannerAspectRatio)), frame.RectTransform),
|
||||||
playStyleBannerSprite, null, true);
|
playStyleBannerSprite, null, true);
|
||||||
|
|
||||||
var playStyleName = new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.0f), playStyleBanner.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.06f) },
|
var playStyleName = new GUITextBlock(
|
||||||
TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"), TextManager.Get("servertag."+ playStyle)), textColor: Color.White,
|
new RectTransform(new Vector2(0.15f, 0.0f), playStyleBanner.RectTransform)
|
||||||
|
{ RelativeOffset = new Vector2(0.0f, 0.06f) },
|
||||||
|
TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"),
|
||||||
|
TextManager.Get("servertag." + playStyle)), textColor: Color.White,
|
||||||
font: GUIStyle.SmallFont, textAlignment: Alignment.Center,
|
font: GUIStyle.SmallFont, textAlignment: Alignment.Center,
|
||||||
color: ServerListScreen.PlayStyleColors[(int)playStyle], style: "GUISlopedHeader");
|
color: ServerListScreen.PlayStyleColors[(int)playStyle], style: "GUISlopedHeader");
|
||||||
playStyleName.RectTransform.NonScaledSize = (playStyleName.Font.MeasureString(playStyleName.Text) + new Vector2(20, 5) * GUI.Scale).ToPoint();
|
playStyleName.RectTransform.NonScaledSize = (playStyleName.Font.MeasureString(playStyleName.Text) + new Vector2(20, 5) * GUI.Scale).ToPoint();
|
||||||
playStyleName.RectTransform.IsFixedSize = true;
|
playStyleName.RectTransform.IsFixedSize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var serverType = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
var serverType = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
||||||
TextManager.Get((OwnerID != 0 || LobbyID != 0) ? "SteamP2PServer" : "DedicatedServer"), textAlignment: Alignment.TopLeft);
|
TextManager.Get((OwnerID != 0 || LobbyID != 0) ? "SteamP2PServer" : "DedicatedServer"),
|
||||||
|
textAlignment: Alignment.TopLeft)
|
||||||
|
{
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
serverType.RectTransform.MinSize = new Point(0, (int)(serverType.Rect.Height * 1.5f));
|
serverType.RectTransform.MinSize = new Point(0, (int)(serverType.Rect.Height * 1.5f));
|
||||||
|
|
||||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), frame.RectTransform))
|
var content = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), frame.RectTransform))
|
||||||
@@ -270,7 +265,11 @@ namespace Barotrauma.Networking
|
|||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||||
TextManager.Get("ServerListContentPackages"), textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
|
TextManager.Get("ServerListContentPackages"), textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
|
||||||
|
|
||||||
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), frame.RectTransform)) { ScrollBarVisible = true };
|
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), frame.RectTransform))
|
||||||
|
{
|
||||||
|
ScrollBarVisible = true,
|
||||||
|
OnSelected = (component, o) => false
|
||||||
|
};
|
||||||
if (ContentPackageNames.Count == 0)
|
if (ContentPackageNames.Count == 0)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(Vector2.One, contentPackageList.Content.RectTransform), TextManager.Get("Unknown"), textAlignment: Alignment.Center)
|
new GUITextBlock(new RectTransform(Vector2.One, contentPackageList.Content.RectTransform), TextManager.Get("Unknown"), textAlignment: Alignment.Center)
|
||||||
@@ -282,28 +281,30 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < ContentPackageNames.Count; i++)
|
for (int i = 0; i < ContentPackageNames.Count; i++)
|
||||||
{
|
{
|
||||||
var packageText = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.15f), contentPackageList.Content.RectTransform) { MinSize = new Point(0, 15) },
|
var packageText = new GUITickBox(
|
||||||
|
new RectTransform(new Vector2(1.0f, 0.15f), contentPackageList.Content.RectTransform)
|
||||||
|
{ MinSize = new Point(0, 15) },
|
||||||
ContentPackageNames[i])
|
ContentPackageNames[i])
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
Enabled = false
|
||||||
};
|
};
|
||||||
|
packageText.Box.Enabled = true;
|
||||||
|
packageText.TextBlock.Enabled = true;
|
||||||
if (i < ContentPackageHashes.Count)
|
if (i < ContentPackageHashes.Count)
|
||||||
{
|
{
|
||||||
if (ContentPackageManager.AllPackages.Any(contentPackage => contentPackage.Hash.StringRepresentation == ContentPackageHashes[i]))
|
if (ContentPackageManager.AllPackages.Any(contentPackage => contentPackage.Hash.StringRepresentation == ContentPackageHashes[i]))
|
||||||
{
|
{
|
||||||
|
packageText.TextColor = GUIStyle.Green;
|
||||||
packageText.Selected = true;
|
packageText.Selected = true;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//workshop download link found
|
//workshop download link found
|
||||||
if (i < ContentPackageWorkshopIds.Count && ContentPackageWorkshopIds[i] != 0)
|
else if (i < ContentPackageWorkshopIds.Count && ContentPackageWorkshopIds[i] != 0)
|
||||||
{
|
{
|
||||||
packageText.TextColor = GUIStyle.Yellow;
|
|
||||||
packageText.ToolTip = TextManager.GetWithVariable("ServerListIncompatibleContentPackageWorkshopAvailable", "[contentpackage]", ContentPackageNames[i]);
|
packageText.ToolTip = TextManager.GetWithVariable("ServerListIncompatibleContentPackageWorkshopAvailable", "[contentpackage]", ContentPackageNames[i]);
|
||||||
}
|
}
|
||||||
else //no package or workshop download link found, tough luck
|
else //no package or workshop download link found (TODO: update text to say that they could be downloaded through the server)
|
||||||
{
|
{
|
||||||
packageText.TextColor = GUIStyle.Red;
|
packageText.TextColor = GameMain.VanillaContent.NameMatches(ContentPackageNames[i]) ? GUIStyle.Red : GUIStyle.Yellow;
|
||||||
packageText.ToolTip = TextManager.GetWithVariables("ServerListIncompatibleContentPackage",
|
packageText.ToolTip = TextManager.GetWithVariables("ServerListIncompatibleContentPackage",
|
||||||
("[contentpackage]", ContentPackageNames[i]), ("[hash]", ContentPackageHashes[i]));
|
("[contentpackage]", ContentPackageNames[i]), ("[hash]", ContentPackageHashes[i]));
|
||||||
}
|
}
|
||||||
@@ -342,7 +343,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
if (ContentPackageNames.Count > 0)
|
if (ContentPackageNames.Count > 0)
|
||||||
{
|
{
|
||||||
tags.Add(ContentPackageNames.Count > 1 || ContentPackageNames[0] != GameMain.VanillaContent?.Name ? "modded.true" : "modded.false");
|
tags.Add(ContentPackageNames.Count > 1 || !GameMain.VanillaContent.NameMatches(ContentPackageNames[0]) ? "modded.true" : "modded.false");
|
||||||
}
|
}
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ namespace Barotrauma.Particles
|
|||||||
Hull collidedHull = Hull.FindHull(position);
|
Hull collidedHull = Hull.FindHull(position);
|
||||||
if (collidedHull != null)
|
if (collidedHull != null)
|
||||||
{
|
{
|
||||||
if (prefab.DeleteOnCollision) return UpdateResult.Delete;
|
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
|
||||||
OnWallCollisionOutside(collidedHull);
|
OnWallCollisionOutside(collidedHull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,20 +346,10 @@ namespace Barotrauma.Particles
|
|||||||
Vector2 collisionNormal = Vector2.Zero;
|
Vector2 collisionNormal = Vector2.Zero;
|
||||||
if (velocity.Y < 0.0f && position.Y - prefab.CollisionRadius * size.Y < hullRect.Y - hullRect.Height)
|
if (velocity.Y < 0.0f && position.Y - prefab.CollisionRadius * size.Y < hullRect.Y - hullRect.Height)
|
||||||
{
|
{
|
||||||
if (prefab.DeleteOnCollision)
|
|
||||||
{
|
|
||||||
OnCollision?.Invoke(position, currentHull);
|
|
||||||
return UpdateResult.Delete;
|
|
||||||
}
|
|
||||||
collisionNormal = new Vector2(0.0f, 1.0f);
|
collisionNormal = new Vector2(0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
else if (velocity.Y > 0.0f && position.Y + prefab.CollisionRadius * size.Y > hullRect.Y)
|
else if (velocity.Y > 0.0f && position.Y + prefab.CollisionRadius * size.Y > hullRect.Y)
|
||||||
{
|
{
|
||||||
if (prefab.DeleteOnCollision)
|
|
||||||
{
|
|
||||||
OnCollision?.Invoke(position, currentHull);
|
|
||||||
return UpdateResult.Delete;
|
|
||||||
}
|
|
||||||
collisionNormal = new Vector2(0.0f, -1.0f);
|
collisionNormal = new Vector2(0.0f, -1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,18 +369,21 @@ namespace Barotrauma.Particles
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prefab.DeleteOnCollision && !gapFound)
|
||||||
|
{
|
||||||
|
OnCollision?.Invoke(position, currentHull);
|
||||||
|
return UpdateResult.Delete;
|
||||||
|
}
|
||||||
handleCollision(gapFound, collisionNormal);
|
handleCollision(gapFound, collisionNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
collisionNormal = Vector2.Zero;
|
collisionNormal = Vector2.Zero;
|
||||||
if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < hullRect.X)
|
if (velocity.X < 0.0f && position.X - prefab.CollisionRadius * size.X < hullRect.X)
|
||||||
{
|
{
|
||||||
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
|
|
||||||
collisionNormal = new Vector2(1.0f, 0.0f);
|
collisionNormal = new Vector2(1.0f, 0.0f);
|
||||||
}
|
}
|
||||||
else if (velocity.X > 0.0f && position.X + prefab.CollisionRadius * size.X > hullRect.Right)
|
else if (velocity.X > 0.0f && position.X + prefab.CollisionRadius * size.X > hullRect.Right)
|
||||||
{
|
{
|
||||||
if (prefab.DeleteOnCollision) { return UpdateResult.Delete; }
|
|
||||||
collisionNormal = new Vector2(-1.0f, 0.0f);
|
collisionNormal = new Vector2(-1.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +401,11 @@ namespace Barotrauma.Particles
|
|||||||
gapFound = true;
|
gapFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (prefab.DeleteOnCollision && !gapFound)
|
||||||
|
{
|
||||||
|
OnCollision?.Invoke(position, currentHull);
|
||||||
|
return UpdateResult.Delete;
|
||||||
|
}
|
||||||
handleCollision(gapFound, collisionNormal);
|
handleCollision(gapFound, collisionNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,7 +509,7 @@ namespace Barotrauma.Particles
|
|||||||
{
|
{
|
||||||
Rectangle hullRect = collisionHull.WorldRect;
|
Rectangle hullRect = collisionHull.WorldRect;
|
||||||
|
|
||||||
Vector2 center = new Vector2(hullRect.X + hullRect.Width /2, hullRect.Y - hullRect.Height / 2);
|
Vector2 center = new Vector2(hullRect.X + hullRect.Width / 2, hullRect.Y - hullRect.Height / 2);
|
||||||
|
|
||||||
if (position.Y < center.Y)
|
if (position.Y < center.Y)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Barotrauma
|
|||||||
Hull.EditFire = false;
|
Hull.EditFire = false;
|
||||||
Hull.EditWater = false;
|
Hull.EditWater = false;
|
||||||
#endif
|
#endif
|
||||||
|
HumanAIController.DisableCrewAI = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void DeselectEditorSpecific() { }
|
protected virtual void DeselectEditorSpecific() { }
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connection.OverrideValue = Convert.ChangeType(overrideValue, type);
|
connection.OverrideValue = EventEditorScreen.ChangeType(overrideValue, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,7 +513,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newNode.Value = Convert.ChangeType(value, type);
|
newNode.Value = EventEditorScreen.ChangeType(value, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connection.OverrideValue = Convert.ChangeType(attribute.Value, connection.ValueType);
|
connection.OverrideValue = ChangeType(attribute.Value, connection.ValueType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,6 +524,18 @@ namespace Barotrauma
|
|||||||
GuiFrame.AddToGUIUpdateList();
|
GuiFrame.AddToGUIUpdateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object? ChangeType(string value, Type type)
|
||||||
|
{
|
||||||
|
if (type == typeof(Identifier))
|
||||||
|
{
|
||||||
|
return value.ToIdentifier();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Convert.ChangeType(value, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private XElement? ExportXML()
|
private XElement? ExportXML()
|
||||||
{
|
{
|
||||||
XElement mainElement = new XElement("ScriptedEvent", new XAttribute("identifier", projectName.RemoveWhitespace().ToLowerInvariant()));
|
XElement mainElement = new XElement("ScriptedEvent", new XAttribute("identifier", projectName.RemoveWhitespace().ToLowerInvariant()));
|
||||||
|
|||||||
@@ -883,12 +883,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void SerializeAll()
|
private void SerializeAll()
|
||||||
{
|
{
|
||||||
|
IEnumerable<ContentPackage> packages = ContentPackageManager.LocalPackages;
|
||||||
|
#if DEBUG
|
||||||
|
packages = packages.Union(ContentPackageManager.VanillaCorePackage.ToEnumerable());
|
||||||
|
#endif
|
||||||
|
|
||||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||||
{
|
{
|
||||||
Indent = true,
|
Indent = true,
|
||||||
NewLineOnAttributes = true
|
NewLineOnAttributes = true
|
||||||
};
|
};
|
||||||
foreach (var configFile in ContentPackageManager.AllPackages.SelectMany(p => p.GetFiles<LevelGenerationParametersFile>()))
|
foreach (var configFile in packages.SelectMany(p => p.GetFiles<LevelGenerationParametersFile>()))
|
||||||
{
|
{
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
||||||
if (doc == null) { continue; }
|
if (doc == null) { continue; }
|
||||||
@@ -922,7 +927,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var configFile in ContentPackageManager.AllPackages.SelectMany(p => p.GetFiles<CaveGenerationParametersFile>()))
|
foreach (var configFile in packages.SelectMany(p => p.GetFiles<CaveGenerationParametersFile>()))
|
||||||
{
|
{
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
||||||
if (doc == null) { continue; }
|
if (doc == null) { continue; }
|
||||||
@@ -957,7 +962,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
settings.NewLineOnAttributes = false;
|
settings.NewLineOnAttributes = false;
|
||||||
foreach (var configFile in ContentPackageManager.AllPackages.SelectMany(p => p.GetFiles<LevelObjectPrefabsFile>()))
|
foreach (var configFile in packages.SelectMany(p => p.GetFiles<LevelObjectPrefabsFile>()))
|
||||||
{
|
{
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);
|
||||||
if (doc == null) { continue; }
|
if (doc == null) { continue; }
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using Barotrauma.Networking;
|
|||||||
using Barotrauma.Steam;
|
using Barotrauma.Steam;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Steamworks.Data;
|
|
||||||
using Color = Microsoft.Xna.Framework.Color;
|
using Color = Microsoft.Xna.Framework.Color;
|
||||||
using ServerContentPackage = Barotrauma.Networking.ClientPeer.ServerContentPackage;
|
using ServerContentPackage = Barotrauma.Networking.ClientPeer.ServerContentPackage;
|
||||||
|
|
||||||
@@ -164,7 +163,7 @@ namespace Barotrauma
|
|||||||
=> wp.SteamWorkshopId != mp.WorkshopId))
|
=> wp.SteamWorkshopId != mp.WorkshopId))
|
||||||
.Select(mp => mp.WorkshopId)
|
.Select(mp => mp.WorkshopId)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
if (missingIds.Any())
|
if (missingIds.Any() && SteamManager.IsInitialized)
|
||||||
{
|
{
|
||||||
buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), innerLayout.RectTransform), isHorizontal: true);
|
buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), innerLayout.RectTransform), isHorizontal: true);
|
||||||
buttonContainerSpacing(0.15f);
|
buttonContainerSpacing(0.15f);
|
||||||
@@ -208,7 +207,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (currentDownload == p)
|
if (currentDownload == p)
|
||||||
{
|
{
|
||||||
FileReceiver.FileTransferIn? getTransfer() => GameMain.Client.FileReceiver.ActiveTransfers.FirstOrDefault(t => t.FileType == FileTransferType.Mod);
|
FileReceiver.FileTransferIn? getTransfer() => GameMain.Client?.FileReceiver.ActiveTransfers.FirstOrDefault(t => t.FileType == FileTransferType.Mod);
|
||||||
|
|
||||||
if (downloadProgress.GetAnyChild<GUITextBlock>() is null)
|
if (downloadProgress.GetAnyChild<GUITextBlock>() is null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2298,7 +2298,7 @@ namespace Barotrauma
|
|||||||
text: selectedClient.Name, font: GUIStyle.LargeFont);
|
text: selectedClient.Name, font: GUIStyle.LargeFont);
|
||||||
nameText.Text = ToolBox.LimitString(nameText.Text, nameText.Font, (int)(nameText.Rect.Width * 0.95f));
|
nameText.Text = ToolBox.LimitString(nameText.Text, nameText.Font, (int)(nameText.Rect.Width * 0.95f));
|
||||||
|
|
||||||
if (hasManagePermissions)
|
if (hasManagePermissions && !selectedClient.IsOwner)
|
||||||
{
|
{
|
||||||
PlayerFrame.UserData = selectedClient;
|
PlayerFrame.UserData = selectedClient;
|
||||||
|
|
||||||
|
|||||||
@@ -557,7 +557,9 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
serverPreview = new GUIListBox(new RectTransform(Vector2.One, serverPreviewContainer.RectTransform, Anchor.Center))
|
serverPreview = new GUIListBox(new RectTransform(Vector2.One, serverPreviewContainer.RectTransform, Anchor.Center))
|
||||||
{
|
{
|
||||||
Padding = Vector4.One * 10 * GUI.Scale
|
Padding = Vector4.One * 10 * GUI.Scale,
|
||||||
|
HoverCursor = CursorState.Default,
|
||||||
|
OnSelected = (component, o) => false
|
||||||
};
|
};
|
||||||
|
|
||||||
// Spacing
|
// Spacing
|
||||||
@@ -915,12 +917,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
case "ServerListCompatible":
|
case "ServerListCompatible":
|
||||||
bool? s1Compatible = NetworkMember.IsCompatible(GameMain.Version.ToString(), s1.GameVersion);
|
bool? s1Compatible = NetworkMember.IsCompatible(GameMain.Version.ToString(), s1.GameVersion);
|
||||||
if (!s1.ContentPackageHashes.Any()) { s1Compatible = null; }
|
|
||||||
if (s1Compatible.HasValue) { s1Compatible = s1Compatible.Value && s1.ContentPackagesMatch(); };
|
|
||||||
|
|
||||||
bool? s2Compatible = NetworkMember.IsCompatible(GameMain.Version.ToString(), s2.GameVersion);
|
bool? s2Compatible = NetworkMember.IsCompatible(GameMain.Version.ToString(), s2.GameVersion);
|
||||||
if (!s2.ContentPackageHashes.Any()) { s2Compatible = null; }
|
|
||||||
if (s2Compatible.HasValue) { s2Compatible = s2Compatible.Value && s2.ContentPackagesMatch(); };
|
|
||||||
|
|
||||||
//convert to int to make sorting easier
|
//convert to int to make sorting easier
|
||||||
//1 Compatible
|
//1 Compatible
|
||||||
@@ -1028,8 +1025,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (GUIComponent child in serverList.Content.Children)
|
foreach (GUIComponent child in serverList.Content.Children)
|
||||||
{
|
{
|
||||||
if (!(child.UserData is ServerInfo)) continue;
|
if (!(child.UserData is ServerInfo serverInfo)) { continue; }
|
||||||
ServerInfo serverInfo = (ServerInfo)child.UserData;
|
|
||||||
|
|
||||||
Version remoteVersion = null;
|
Version remoteVersion = null;
|
||||||
if (!string.IsNullOrEmpty(serverInfo.GameVersion))
|
if (!string.IsNullOrEmpty(serverInfo.GameVersion))
|
||||||
@@ -1047,8 +1043,7 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool incompatible =
|
bool incompatible =
|
||||||
(serverInfo.ContentPackageHashes.Any() && !serverInfo.ContentPackagesMatch()) ||
|
remoteVersion != null && !NetworkMember.IsCompatible(GameMain.Version, remoteVersion);
|
||||||
(remoteVersion != null && !NetworkMember.IsCompatible(GameMain.Version, remoteVersion));
|
|
||||||
|
|
||||||
var karmaFilterPassed = filterKarmaValue == TernaryOption.Any|| (filterKarmaValue == TernaryOption.Enabled) == serverInfo.KarmaEnabled;
|
var karmaFilterPassed = filterKarmaValue == TernaryOption.Any|| (filterKarmaValue == TernaryOption.Enabled) == serverInfo.KarmaEnabled;
|
||||||
var friendlyFireFilterPassed = filterFriendlyFireValue == TernaryOption.Any || (filterFriendlyFireValue == TernaryOption.Enabled) == serverInfo.FriendlyFireEnabled;
|
var friendlyFireFilterPassed = filterFriendlyFireValue == TernaryOption.Any || (filterFriendlyFireValue == TernaryOption.Enabled) == serverInfo.FriendlyFireEnabled;
|
||||||
@@ -1798,8 +1793,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
Selected =
|
Selected =
|
||||||
(NetworkMember.IsCompatible(GameMain.Version.ToString(), serverInfo.GameVersion) ?? true) &&
|
(NetworkMember.IsCompatible(GameMain.Version.ToString(), serverInfo.GameVersion) ?? true),
|
||||||
serverInfo.ContentPackagesMatch(),
|
|
||||||
UserData = "compatible"
|
UserData = "compatible"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1826,9 +1820,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (serverInfo.ContentPackageNames.Any())
|
if (serverInfo.ContentPackageNames.Any())
|
||||||
{
|
{
|
||||||
if (serverInfo.ContentPackageNames.Any(cp => !cp.Equals(GameMain.VanillaContent.Name, StringComparison.OrdinalIgnoreCase)))
|
if (serverInfo.ContentPackageNames.Any(p => !GameMain.VanillaContent.NameMatches(p)))
|
||||||
{
|
{
|
||||||
serverName.TextColor = new Color(219, 125, 217);
|
serverName.TextColor = GUIStyle.ModdedServerColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2841,6 +2841,7 @@ namespace Barotrauma
|
|||||||
private void CreateLoadScreen()
|
private void CreateLoadScreen()
|
||||||
{
|
{
|
||||||
CloseItem();
|
CloseItem();
|
||||||
|
SubmarineInfo.RefreshSavedSubs();
|
||||||
SetMode(Mode.Default);
|
SetMode(Mode.Default);
|
||||||
|
|
||||||
loadFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null)
|
loadFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null)
|
||||||
@@ -3162,7 +3163,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub.Dispose();
|
sub.Dispose();
|
||||||
SubmarineInfo.RefreshSavedSubs();
|
|
||||||
CreateLoadScreen();
|
CreateLoadScreen();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
@@ -168,7 +168,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var dropdown = new GUIDropDown(NewItemRectT(parent));
|
var dropdown = new GUIDropDown(NewItemRectT(parent));
|
||||||
values.ForEach(v => dropdown.AddItem(text: textFunc(v), userData: v, toolTip: tooltipFunc?.Invoke(v) ?? null));
|
values.ForEach(v => dropdown.AddItem(text: textFunc(v), userData: v, toolTip: tooltipFunc?.Invoke(v) ?? null));
|
||||||
dropdown.Select(values.IndexOf(currentValue));
|
int childIndex = values.IndexOf(currentValue);
|
||||||
|
dropdown.Select(childIndex);
|
||||||
|
dropdown.ListBox.ForceLayoutRecalculation();
|
||||||
|
dropdown.ListBox.ScrollToElement(dropdown.ListBox.Content.GetChild(childIndex), playSound: false);
|
||||||
dropdown.OnSelected = (dd, obj) =>
|
dropdown.OnSelected = (dd, obj) =>
|
||||||
{
|
{
|
||||||
setter((T)obj);
|
setter((T)obj);
|
||||||
@@ -231,6 +234,8 @@ namespace Barotrauma
|
|||||||
GameMain.GraphicsDeviceManager.GraphicsDevice.Adapter.SupportedDisplayModes
|
GameMain.GraphicsDeviceManager.GraphicsDevice.Adapter.SupportedDisplayModes
|
||||||
.Where(m => m.Format == SurfaceFormat.Color)
|
.Where(m => m.Format == SurfaceFormat.Color)
|
||||||
.Select(m => (m.Width, m.Height))
|
.Select(m => (m.Width, m.Height))
|
||||||
|
.Where(m => m.Width >= GameSettings.Config.GraphicsSettings.MinSupportedResolution.X
|
||||||
|
&& m.Height >= GameSettings.Config.GraphicsSettings.MinSupportedResolution.Y)
|
||||||
.ToList();
|
.ToList();
|
||||||
var currentResolution = (unsavedConfig.Graphics.Width, unsavedConfig.Graphics.Height);
|
var currentResolution = (unsavedConfig.Graphics.Width, unsavedConfig.Graphics.Height);
|
||||||
if (!supportedResolutions.Contains(currentResolution))
|
if (!supportedResolutions.Contains(currentResolution))
|
||||||
|
|||||||
@@ -372,13 +372,10 @@ namespace Barotrauma.Sounds
|
|||||||
}
|
}
|
||||||
|
|
||||||
var newSound = new OggSound(this, filePath, stream, xElement: element);
|
var newSound = new OggSound(this, filePath, stream, xElement: element);
|
||||||
if (newSound != null)
|
newSound.BaseGain = element.GetAttributeFloat("volume", 1.0f);
|
||||||
{
|
float range = element.GetAttributeFloat("range", 1000.0f);
|
||||||
newSound.BaseGain = element.GetAttributeFloat("volume", 1.0f);
|
newSound.BaseNear = range * 0.4f;
|
||||||
float range = element.GetAttributeFloat("range", 1000.0f);
|
newSound.BaseFar = range;
|
||||||
newSound.BaseNear = range * 0.4f;
|
|
||||||
newSound.BaseFar = range;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (loadedSounds)
|
lock (loadedSounds)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ namespace Barotrauma
|
|||||||
SoundChannel chn = waterAmbienceChannels.FirstOrDefault(c => c.Sound == sound);
|
SoundChannel chn = waterAmbienceChannels.FirstOrDefault(c => c.Sound == sound);
|
||||||
if (chn is null || !chn.IsPlaying)
|
if (chn is null || !chn.IsPlaying)
|
||||||
{
|
{
|
||||||
|
if (volume < 0.01f) { return; }
|
||||||
if (!(chn is null)) { waterAmbienceChannels.Remove(chn); }
|
if (!(chn is null)) { waterAmbienceChannels.Remove(chn); }
|
||||||
chn = sound.Play(volume, "waterambience");
|
chn = sound.Play(volume, "waterambience");
|
||||||
chn.Looping = true;
|
chn.Looping = true;
|
||||||
|
|||||||
@@ -202,6 +202,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Sound?.Dispose(); Sound = null;
|
Sound?.Dispose(); Sound = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~SoundPrefab()
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TagNames("damagesound")]
|
[TagNames("damagesound")]
|
||||||
|
|||||||
@@ -270,8 +270,9 @@ namespace Barotrauma.Steam
|
|||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
toUninstall.Select(p => p.Dir).ForEach(d => Directory.Delete(d));
|
toUninstall.Select(p => p.Dir).ForEach(d => Directory.Delete(d));
|
||||||
CrossThread.RequestExecutionOnMainThread(() => ContentPackageManager.WorkshopPackages.Refresh());
|
CrossThread.RequestExecutionOnMainThread(() => ContentPackageManager.WorkshopPackages.Refresh());
|
||||||
|
var installWaiter = WaitForInstall(workshopItem);
|
||||||
DownloadModThenEnqueueInstall(workshopItem);
|
DownloadModThenEnqueueInstall(workshopItem);
|
||||||
await WaitForInstall(workshopItem);
|
await installWaiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task WaitForInstall(Steamworks.Ugc.Item item)
|
public static async Task WaitForInstall(Steamworks.Ugc.Item item)
|
||||||
|
|||||||
+6
@@ -1,5 +1,6 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
@@ -39,6 +40,11 @@ namespace Barotrauma.Steam
|
|||||||
CanBeFocused = false,
|
CanBeFocused = false,
|
||||||
UserData = p
|
UserData = p
|
||||||
};
|
};
|
||||||
|
if (p.Errors.Any())
|
||||||
|
{
|
||||||
|
CreateModErrorInfo(p, regularBox, regularBox);
|
||||||
|
regularBox.CanBeFocused = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
filterBox = CreateSearchBox(mainLayout, width: 1.0f);
|
filterBox = CreateSearchBox(mainLayout, width: 1.0f);
|
||||||
|
|
||||||
|
|||||||
+45
-3
@@ -20,10 +20,10 @@ namespace Barotrauma.Steam
|
|||||||
Publish
|
Publish
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly GUILayoutGroup tabber;
|
private readonly GUILayoutGroup tabber;
|
||||||
protected readonly Dictionary<Tab, (GUIButton Button, GUIFrame Content)> tabContents;
|
private readonly Dictionary<Tab, (GUIButton Button, GUIFrame Content)> tabContents;
|
||||||
|
|
||||||
protected readonly GUIFrame contentFrame;
|
private readonly GUIFrame contentFrame;
|
||||||
|
|
||||||
private CorePackage EnabledCorePackage => enabledCoreDropdown.SelectedData as CorePackage ?? throw new Exception("Valid core package not selected");
|
private CorePackage EnabledCorePackage => enabledCoreDropdown.SelectedData as CorePackage ?? throw new Exception("Valid core package not selected");
|
||||||
|
|
||||||
@@ -40,6 +40,8 @@ namespace Barotrauma.Steam
|
|||||||
private readonly GUIListBox popularModsList;
|
private readonly GUIListBox popularModsList;
|
||||||
private readonly GUIListBox selfModsList;
|
private readonly GUIListBox selfModsList;
|
||||||
|
|
||||||
|
private uint memSubscribedModCount = 0;
|
||||||
|
|
||||||
public MutableWorkshopMenu(GUIFrame parent) : base(parent)
|
public MutableWorkshopMenu(GUIFrame parent) : base(parent)
|
||||||
{
|
{
|
||||||
var mainLayout
|
var mainLayout
|
||||||
@@ -51,6 +53,9 @@ namespace Barotrauma.Steam
|
|||||||
|
|
||||||
contentFrame = new GUIFrame(new RectTransform((1.0f, 0.95f), mainLayout.RectTransform), style: null);
|
contentFrame = new GUIFrame(new RectTransform((1.0f, 0.95f), mainLayout.RectTransform), style: null);
|
||||||
|
|
||||||
|
new GUICustomComponent(new RectTransform(Vector2.Zero, mainLayout.RectTransform),
|
||||||
|
onUpdate: (f, component) => UpdateSubscribedModInstalls());
|
||||||
|
|
||||||
CreateInstalledModsTab(
|
CreateInstalledModsTab(
|
||||||
out enabledCoreDropdown,
|
out enabledCoreDropdown,
|
||||||
out enabledRegularModsList,
|
out enabledRegularModsList,
|
||||||
@@ -64,6 +69,38 @@ namespace Barotrauma.Steam
|
|||||||
SelectTab(Tab.InstalledMods);
|
SelectTab(Tab.InstalledMods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateSubscribedModInstalls()
|
||||||
|
{
|
||||||
|
if (!SteamManager.IsInitialized) { return; }
|
||||||
|
|
||||||
|
uint numSubscribedMods = Steamworks.SteamUGC.NumSubscribedItems;
|
||||||
|
if (numSubscribedMods == memSubscribedModCount) { return; }
|
||||||
|
memSubscribedModCount = numSubscribedMods;
|
||||||
|
|
||||||
|
var subscribedIds = Steamworks.SteamUGC.GetSubscribedItems().ToHashSet();
|
||||||
|
var installedIds = ContentPackageManager.WorkshopPackages.Select(p => p.SteamWorkshopId).ToHashSet();
|
||||||
|
foreach (var id in subscribedIds.Where(id2 => !installedIds.Contains(id2)))
|
||||||
|
{
|
||||||
|
Steamworks.Ugc.Item item = new Steamworks.Ugc.Item(id);
|
||||||
|
if (!item.IsDownloading && !SteamManager.Workshop.IsInstalling(item))
|
||||||
|
{
|
||||||
|
SteamManager.Workshop.DownloadModThenEnqueueInstall(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskPool.Add("RemoveUnsubscribedItems", SteamManager.Workshop.GetPublishedItems(), t =>
|
||||||
|
{
|
||||||
|
if (!t.TryGetResult(out ISet<Steamworks.Ugc.Item> publishedItems)) { return; }
|
||||||
|
|
||||||
|
var allRequiredInstalled = subscribedIds.Union(publishedItems.Select(it => it.Id)).ToHashSet();
|
||||||
|
foreach (var id in installedIds.Where(id2 => !allRequiredInstalled.Contains(id2)))
|
||||||
|
{
|
||||||
|
Steamworks.Ugc.Item item = new Steamworks.Ugc.Item(id);
|
||||||
|
SteamManager.Workshop.Uninstall(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void SwitchContent(GUIFrame newContent)
|
private void SwitchContent(GUIFrame newContent)
|
||||||
{
|
{
|
||||||
contentFrame.Children.ForEach(c => c.Visible = false);
|
contentFrame.Children.ForEach(c => c.Visible = false);
|
||||||
@@ -462,6 +499,10 @@ namespace Barotrauma.Steam
|
|||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
if (mod.Errors.Any())
|
||||||
|
{
|
||||||
|
CreateModErrorInfo(mod, modFrame, modName);
|
||||||
|
}
|
||||||
if (ContentPackageManager.LocalPackages.Contains(mod))
|
if (ContentPackageManager.LocalPackages.Contains(mod))
|
||||||
{
|
{
|
||||||
var editButton = new GUIButton(new RectTransform(Vector2.One, frameContent.RectTransform, scaleBasis: ScaleBasis.Smallest), "",
|
var editButton = new GUIButton(new RectTransform(Vector2.One, frameContent.RectTransform, scaleBasis: ScaleBasis.Smallest), "",
|
||||||
@@ -593,6 +634,7 @@ namespace Barotrauma.Steam
|
|||||||
ContentPackageManager.EnabledPackages.SetRegular(enabledRegularModsList.Content.Children
|
ContentPackageManager.EnabledPackages.SetRegular(enabledRegularModsList.Content.Children
|
||||||
.Select(c => c.UserData as RegularPackage).OfType<RegularPackage>().ToArray());
|
.Select(c => c.UserData as RegularPackage).OfType<RegularPackage>().ToArray());
|
||||||
PopulateInstalledModLists(forceRefreshEnabled: true, refreshDisabled: true);
|
PopulateInstalledModLists(forceRefreshEnabled: true, refreshDisabled: true);
|
||||||
|
ContentPackageManager.LogEnabledRegularPackageErrors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,5 +129,20 @@ namespace Barotrauma.Steam
|
|||||||
};
|
};
|
||||||
return searchBox;
|
return searchBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void CreateModErrorInfo(ContentPackage mod, GUIComponent uiElement, GUITextBlock nameText)
|
||||||
|
{
|
||||||
|
if (mod.Errors.Any())
|
||||||
|
{
|
||||||
|
const int maxErrorsToShow = 5;
|
||||||
|
nameText.TextColor = GUIStyle.Red;
|
||||||
|
uiElement.ToolTip =
|
||||||
|
TextManager.GetWithVariable("contentpackagehaserrors", "[packagename]", mod.Name) + '\n' + string.Join('\n', mod.Errors.Take(maxErrorsToShow).Select(e => e.error));
|
||||||
|
if (mod.Errors.Count() > maxErrorsToShow)
|
||||||
|
{
|
||||||
|
uiElement.ToolTip += '\n' + TextManager.GetWithVariable("workshopitemdownloadprompttruncated", "[number]", (mod.Errors.Count() - maxErrorsToShow).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.17.6.0</Version>
|
<Version>0.17.7.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.17.6.0</Version>
|
<Version>0.17.7.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.17.6.0</Version>
|
<Version>0.17.7.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.17.6.0</Version>
|
<Version>0.17.7.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.17.6.0</Version>
|
<Version>0.17.7.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ namespace Barotrauma
|
|||||||
GameModePreset.Init();
|
GameModePreset.Init();
|
||||||
|
|
||||||
ContentPackageManager.Init().Consume();
|
ContentPackageManager.Init().Consume();
|
||||||
|
ContentPackageManager.LogEnabledRegularPackageErrors();
|
||||||
|
|
||||||
SubmarineInfo.RefreshSavedSubs();
|
SubmarineInfo.RefreshSavedSubs();
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -922,13 +922,12 @@ namespace Barotrauma
|
|||||||
if (transfer.Receiver is Some<ushort> { Value: var receiverId } && receiverId == sender.CharacterID)
|
if (transfer.Receiver is Some<ushort> { Value: var receiverId } && receiverId == sender.CharacterID)
|
||||||
{
|
{
|
||||||
GameMain.Server?.Voting.StartTransferVote(sender, null, transfer.Amount, sender);
|
GameMain.Server?.Voting.StartTransferVote(sender, null, transfer.Amount, sender);
|
||||||
|
GameServer.Log($"{sender.Name} started a vote to transfer {transfer.Amount} mk from the bank.", ServerLog.MessageType.Money);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
TransferMoney(Bank);
|
||||||
TransferMoney(Bank);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,9 +942,11 @@ namespace Barotrauma
|
|||||||
if (wallet is InvalidWallet) { return; }
|
if (wallet is InvalidWallet) { return; }
|
||||||
|
|
||||||
wallet.Give(transfer.Amount);
|
wallet.Give(transfer.Amount);
|
||||||
|
GameServer.Log($"{sender.Name} transferred {transfer.Amount} mk to {wallet.GetOwnerLogName()} from {from.GetOwnerLogName()}.", ServerLog.MessageType.Money);
|
||||||
break;
|
break;
|
||||||
case None<ushort> _:
|
case None<ushort> _:
|
||||||
Bank.Give(transfer.Amount);
|
Bank.Give(transfer.Amount);
|
||||||
|
GameServer.Log($"{sender.Name} transferred {transfer.Amount} mk to {Bank.GetOwnerLogName()} from {from.GetOwnerLogName()}.", ServerLog.MessageType.Money);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -965,6 +966,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Character targetCharacter = Character.CharacterList.FirstOrDefault(c => c.ID == update.Target);
|
Character targetCharacter = Character.CharacterList.FirstOrDefault(c => c.ID == update.Target);
|
||||||
targetCharacter?.Wallet.SetRewardDistribution(update.NewRewardDistribution);
|
targetCharacter?.Wallet.SetRewardDistribution(update.NewRewardDistribution);
|
||||||
|
GameServer.Log($"{sender.Name} changed the salary of {targetCharacter?.Name ?? "the bank"} to {update.NewRewardDistribution}%.", ServerLog.MessageType.Money);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ServerReadCrew(IReadMessage msg, Client sender)
|
public void ServerReadCrew(IReadMessage msg, Client sender)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
//setting a wait timer means that network conditions
|
//setting a wait timer means that network conditions
|
||||||
//aren't ideal, slow down the packet rate
|
//aren't ideal, slow down the packet rate
|
||||||
PacketsPerUpdate = Math.Max(PacketsPerUpdate / 2.0f, 1.0f);
|
PacketsPerUpdate = Math.Max(PacketsPerUpdate / 4.0f, 1.0f);
|
||||||
}
|
}
|
||||||
waitTimer = value;
|
waitTimer = value;
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ namespace Barotrauma.Networking
|
|||||||
public FileSender(ServerPeer serverPeer, int mtu)
|
public FileSender(ServerPeer serverPeer, int mtu)
|
||||||
{
|
{
|
||||||
peer = serverPeer;
|
peer = serverPeer;
|
||||||
chunkLen = mtu - 100;
|
chunkLen = mtu - 200;
|
||||||
|
|
||||||
activeTransfers = new List<FileTransferOut>();
|
activeTransfers = new List<FileTransferOut>();
|
||||||
}
|
}
|
||||||
@@ -197,11 +197,8 @@ namespace Barotrauma.Networking
|
|||||||
foreach (FileTransferOut transfer in activeTransfers)
|
foreach (FileTransferOut transfer in activeTransfers)
|
||||||
{
|
{
|
||||||
transfer.WaitTimer -= deltaTime;
|
transfer.WaitTimer -= deltaTime;
|
||||||
for (int i = 0; i < 10; i++)
|
if (transfer.WaitTimer > 0.0f) { continue; }
|
||||||
{
|
Send(transfer);
|
||||||
if (transfer.WaitTimer > 0.0f) { break; }
|
|
||||||
Send(transfer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numRemoved > 0 || endedTransfers.Count > 0)
|
if (numRemoved > 0 || endedTransfers.Count > 0)
|
||||||
@@ -281,7 +278,7 @@ namespace Barotrauma.Networking
|
|||||||
if (transfer.SentOffset >= transfer.Data.Length)
|
if (transfer.SentOffset >= transfer.Data.Length)
|
||||||
{
|
{
|
||||||
transfer.SentOffset = transfer.KnownReceivedOffset;
|
transfer.SentOffset = transfer.KnownReceivedOffset;
|
||||||
transfer.WaitTimer = 0.5f;
|
transfer.WaitTimer = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable, compressPastThreshold: false);
|
peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable, compressPastThreshold: false);
|
||||||
@@ -356,7 +353,7 @@ namespace Barotrauma.Networking
|
|||||||
matchingTransfer.SentOffset >= matchingTransfer.Data.Length)
|
matchingTransfer.SentOffset >= matchingTransfer.Data.Length)
|
||||||
{
|
{
|
||||||
matchingTransfer.SentOffset = matchingTransfer.KnownReceivedOffset;
|
matchingTransfer.SentOffset = matchingTransfer.KnownReceivedOffset;
|
||||||
matchingTransfer.WaitTimer = 0.5f;
|
matchingTransfer.WaitTimer = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchingTransfer.KnownReceivedOffset >= matchingTransfer.Data.Length)
|
if (matchingTransfer.KnownReceivedOffset >= matchingTransfer.Data.Length)
|
||||||
@@ -364,6 +361,7 @@ namespace Barotrauma.Networking
|
|||||||
matchingTransfer.Status = FileTransferStatus.Finished;
|
matchingTransfer.Status = FileTransferStatus.Finished;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileTransferType fileType = (FileTransferType)inc.ReadByte();
|
FileTransferType fileType = (FileTransferType)inc.ReadByte();
|
||||||
|
|||||||
@@ -91,13 +91,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void StartSubmarineVote(SubmarineInfo subInfo, VoteType voteType, Client sender)
|
private void StartSubmarineVote(SubmarineInfo subInfo, VoteType voteType, Client sender)
|
||||||
{
|
{
|
||||||
|
if (ActiveVote == null)
|
||||||
|
{
|
||||||
|
sender.SetVote(voteType, 2);
|
||||||
|
}
|
||||||
var subVote = new SubmarineVote(
|
var subVote = new SubmarineVote(
|
||||||
sender,
|
sender,
|
||||||
subInfo,
|
subInfo,
|
||||||
voteType == VoteType.SwitchSub ? GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation) : 0,
|
voteType == VoteType.SwitchSub ? GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation) : 0,
|
||||||
voteType);
|
voteType);
|
||||||
StartOrEnqueueVote(subVote);
|
StartOrEnqueueVote(subVote);
|
||||||
sender.SetVote(voteType, 2);
|
|
||||||
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,13 +130,17 @@ namespace Barotrauma
|
|||||||
if (pendingVotes.Any())
|
if (pendingVotes.Any())
|
||||||
{
|
{
|
||||||
ActiveVote = pendingVotes.Dequeue();
|
ActiveVote = pendingVotes.Dequeue();
|
||||||
|
ActiveVote.VoteStarter?.SetVote(ActiveVote.VoteType, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartTransferVote(Client starter, Client from, int transferAmount, Client to)
|
public void StartTransferVote(Client starter, Client from, int transferAmount, Client to)
|
||||||
{
|
{
|
||||||
|
if (ActiveVote == null)
|
||||||
|
{
|
||||||
|
starter.SetVote(VoteType.TransferMoney, 2);
|
||||||
|
}
|
||||||
StartOrEnqueueVote(new TransferVote(starter, from, transferAmount, to));
|
StartOrEnqueueVote(new TransferVote(starter, from, transferAmount, to));
|
||||||
starter.SetVote(VoteType.TransferMoney, 2);
|
|
||||||
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.17.6.0</Version>
|
<Version>0.17.7.0</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2022</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ namespace Barotrauma
|
|||||||
private float enemycheckTimer;
|
private float enemycheckTimer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How far other characters can hear reports done by this character (e.g. reports for fires, intruders).
|
/// How far other characters can hear reports done by this character (e.g. reports for fires, intruders). Defaults to infinity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float ReportRange { get; set; }
|
public float ReportRange { get; set; } = float.PositiveInfinity;
|
||||||
|
|
||||||
private float _aimSpeed = 1;
|
private float _aimSpeed = 1;
|
||||||
public float AimSpeed
|
public float AimSpeed
|
||||||
@@ -166,7 +166,6 @@ namespace Barotrauma
|
|||||||
objectiveManager = new AIObjectiveManager(c);
|
objectiveManager = new AIObjectiveManager(c);
|
||||||
reactTimer = GetReactionTime();
|
reactTimer = GetReactionTime();
|
||||||
SortTimer = Rand.Range(0f, sortObjectiveInterval);
|
SortTimer = Rand.Range(0f, sortObjectiveInterval);
|
||||||
ReportRange = Character.IsOnPlayerTeam ? float.PositiveInfinity : 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
|
|||||||
@@ -269,6 +269,18 @@ namespace Barotrauma
|
|||||||
if (!character.AnimController.InWater || character.Submarine != null) { return; }
|
if (!character.AnimController.InWater || character.Submarine != null) { return; }
|
||||||
if (CurrentPath == null || CurrentPath.Unreachable || CurrentPath.Finished) { return; }
|
if (CurrentPath == null || CurrentPath.Unreachable || CurrentPath.Finished) { return; }
|
||||||
if (CurrentPath.CurrentIndex < 0 || CurrentPath.CurrentIndex >= CurrentPath.Nodes.Count - 1) { return; }
|
if (CurrentPath.CurrentIndex < 0 || CurrentPath.CurrentIndex >= CurrentPath.Nodes.Count - 1) { return; }
|
||||||
|
var lastNode = CurrentPath.Nodes.Last();
|
||||||
|
Submarine targetSub = lastNode.Submarine;
|
||||||
|
if (targetSub != null)
|
||||||
|
{
|
||||||
|
float subSize = Math.Max(targetSub.Borders.Size.X, targetSub.Borders.Size.Y) / 2;
|
||||||
|
float margin = 500;
|
||||||
|
if (Vector2.DistanceSquared(character.WorldPosition, targetSub.WorldPosition) < MathUtils.Pow2(subSize + margin))
|
||||||
|
{
|
||||||
|
// Don't skip nodes when close to the target submarine.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if we could skip ahead to NextNode when the character is swimming and using waypoints outside.
|
// Check if we could skip ahead to NextNode when the character is swimming and using waypoints outside.
|
||||||
// Do this to optimize the old path before creating and evaluating a new path.
|
// Do this to optimize the old path before creating and evaluating a new path.
|
||||||
// In general, this is to avoid behavior where:
|
// In general, this is to avoid behavior where:
|
||||||
@@ -280,7 +292,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var waypoint = CurrentPath.Nodes[i];
|
var waypoint = CurrentPath.Nodes[i];
|
||||||
float directDistance = Vector2.DistanceSquared(character.WorldPosition, waypoint.WorldPosition);
|
float directDistance = Vector2.DistanceSquared(character.WorldPosition, waypoint.WorldPosition);
|
||||||
if (directDistance > (pathDistance * pathDistance) || Submarine.PickBody(host.SimPosition, waypoint.SimPosition, collisionCategory: Physics.CollisionLevel | Physics.CollisionWall) != null)
|
if (directDistance > MathUtils.Pow2(pathDistance) || !character.CanSeeTarget(waypoint))
|
||||||
{
|
{
|
||||||
pathDistance -= CurrentPath.GetLength(startIndex: i - 1, endIndex: i);
|
pathDistance -= CurrentPath.GetLength(startIndex: i - 1, endIndex: i);
|
||||||
continue;
|
continue;
|
||||||
@@ -336,6 +348,7 @@ namespace Barotrauma
|
|||||||
return Vector2.Zero;
|
return Vector2.Zero;
|
||||||
}
|
}
|
||||||
Vector2 pos = host.WorldPosition;
|
Vector2 pos = host.WorldPosition;
|
||||||
|
Vector2 diff = currentPath.CurrentNode.WorldPosition - pos;
|
||||||
bool isDiving = character.AnimController.InWater && character.AnimController.HeadInWater;
|
bool isDiving = character.AnimController.InWater && character.AnimController.HeadInWater;
|
||||||
// Only humanoids can climb ladders
|
// Only humanoids can climb ladders
|
||||||
bool canClimb = character.AnimController is HumanoidAnimController && !character.LockHands;
|
bool canClimb = character.AnimController is HumanoidAnimController && !character.LockHands;
|
||||||
@@ -346,7 +359,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
Ladder nextLadder = GetNextLadder();
|
Ladder nextLadder = GetNextLadder();
|
||||||
var ladders = currentLadder ?? nextLadder;
|
var ladders = currentLadder ?? nextLadder;
|
||||||
bool useLadders = canClimb && ladders != null && (!isDiving || Math.Abs(steering.X) < 0.1f && steering.Y > 1);
|
bool useLadders = canClimb && ladders != null && steering.LengthSquared() > 0.1f && (!isDiving || steering.Y > 1);
|
||||||
if (useLadders && character.SelectedConstruction != ladders.Item)
|
if (useLadders && character.SelectedConstruction != ladders.Item)
|
||||||
{
|
{
|
||||||
if (character.CanInteractWith(ladders.Item))
|
if (character.CanInteractWith(ladders.Item))
|
||||||
@@ -374,7 +387,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (character.IsClimbing && useLadders)
|
if (character.IsClimbing && useLadders)
|
||||||
{
|
{
|
||||||
Vector2 diff = currentPath.CurrentNode.WorldPosition - pos;
|
|
||||||
bool nextLadderSameAsCurrent = IsNextLadderSameAsCurrent;
|
bool nextLadderSameAsCurrent = IsNextLadderSameAsCurrent;
|
||||||
if (nextLadderSameAsCurrent || currentLadder != null && nextLadder != null && Math.Abs(currentLadder.Item.Position.X - nextLadder.Item.Position.X) < 50)
|
if (nextLadderSameAsCurrent || currentLadder != null && nextLadder != null && Math.Abs(currentLadder.Item.Position.X - nextLadder.Item.Position.X) < 50)
|
||||||
{
|
{
|
||||||
@@ -398,7 +410,7 @@ namespace Barotrauma
|
|||||||
else if (nextLadder != null && !nextLadderSameAsCurrent)
|
else if (nextLadder != null && !nextLadderSameAsCurrent)
|
||||||
{
|
{
|
||||||
// Try to change the ladder (hatches between two submarines)
|
// Try to change the ladder (hatches between two submarines)
|
||||||
if (character.SelectedConstruction != nextLadder.Item && nextLadder.Item.IsInsideTrigger(character.WorldPosition))
|
if (character.SelectedConstruction != nextLadder.Item && character.CanInteractWith(nextLadder.Item))
|
||||||
{
|
{
|
||||||
if (nextLadder.Item.TryInteract(character, forceSelectKey: true))
|
if (nextLadder.Item.TryInteract(character, forceSelectKey: true))
|
||||||
{
|
{
|
||||||
@@ -406,7 +418,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isAboveFloor || nextLadderSameAsCurrent)
|
if (isAboveFloor || nextLadderSameAsCurrent || nextLadder == null && Math.Abs(diff.Y) < 10)
|
||||||
{
|
{
|
||||||
NextNode(!doorsChecked);
|
NextNode(!doorsChecked);
|
||||||
}
|
}
|
||||||
@@ -484,7 +496,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
return Vector2.Zero;
|
return Vector2.Zero;
|
||||||
}
|
}
|
||||||
return ConvertUnits.ToSimUnits(currentPath.CurrentNode.WorldPosition - pos);
|
return ConvertUnits.ToSimUnits(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NextNode(bool checkDoors)
|
private void NextNode(bool checkDoors)
|
||||||
|
|||||||
+7
-3
@@ -212,10 +212,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override bool CheckObjectiveSpecific()
|
protected override bool CheckObjectiveSpecific()
|
||||||
{
|
{
|
||||||
if (sqrDistance > maxDistance * maxDistance)
|
if (character.Submarine == null || character.Submarine.TeamID != CharacterTeamType.FriendlyNPC)
|
||||||
{
|
{
|
||||||
// The target escaped from us.
|
// Can't lose the target in friendly outposts.
|
||||||
return true;
|
if (sqrDistance > maxDistance * maxDistance)
|
||||||
|
{
|
||||||
|
// The target escaped from us.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return IsEnemyDisabled || (AllowCoolDown && coolDownTimer <= 0);
|
return IsEnemyDisabled || (AllowCoolDown && coolDownTimer <= 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (InWater || !CanWalk)
|
if (InWater || !CanWalk)
|
||||||
{
|
{
|
||||||
return TargetMovement.LengthSquared() > SwimSlowParams.MovementSpeed;
|
return TargetMovement.LengthSquared() > MathUtils.Pow2(SwimSlowParams.MovementSpeed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// used for talents/ability conditions
|
// used for talents/ability conditions
|
||||||
public Item SourceItem { get; }
|
public Item SourceItem { get; set; }
|
||||||
|
|
||||||
public List<Affliction> GetMultipliedAfflictions(float multiplier)
|
public List<Affliction> GetMultipliedAfflictions(float multiplier)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -308,6 +308,10 @@ namespace Barotrauma
|
|||||||
public bool IsHumanoid => Params.Humanoid;
|
public bool IsHumanoid => Params.Humanoid;
|
||||||
public bool IsHusk => Params.Husk;
|
public bool IsHusk => Params.Husk;
|
||||||
|
|
||||||
|
public bool IsMale => info?.IsMale ?? false;
|
||||||
|
|
||||||
|
public bool IsFemale => info?.IsFemale ?? false;
|
||||||
|
|
||||||
public string BloodDecalName => Params.BloodDecal;
|
public string BloodDecalName => Params.BloodDecal;
|
||||||
|
|
||||||
public bool CanSpeak
|
public bool CanSpeak
|
||||||
@@ -557,10 +561,11 @@ namespace Barotrauma
|
|||||||
#if CLIENT
|
#if CLIENT
|
||||||
CharacterHealth.SetHealthBarVisibility(value == null);
|
CharacterHealth.SetHealthBarVisibility(value == null);
|
||||||
#elif SERVER
|
#elif SERVER
|
||||||
if (value is { IsDead: true, Wallet: { Balance: var balance } grabbedWallet })
|
if (value is { IsDead: true, Wallet: { Balance: var balance } grabbedWallet } && balance > 0)
|
||||||
{
|
{
|
||||||
Wallet.Give(balance);
|
Wallet.Give(balance);
|
||||||
grabbedWallet.Deduct(balance);
|
grabbedWallet.Deduct(balance);
|
||||||
|
GameServer.Log($"{Name} grabbed {value.Name}'s body and received {grabbedWallet.Balance} mk.", ServerLog.MessageType.Money);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -3587,21 +3592,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
float attackImpulse = attack.TargetImpulse + attack.TargetForce * attack.ImpactMultiplier * deltaTime;
|
float attackImpulse = attack.TargetImpulse + attack.TargetForce * attack.ImpactMultiplier * deltaTime;
|
||||||
|
|
||||||
AbilityAttackData attackData = new AbilityAttackData(attack, this);
|
AbilityAttackData attackData = new AbilityAttackData(attack, this, attacker);
|
||||||
if (attacker != null)
|
|
||||||
{
|
|
||||||
attackData.Attacker = attacker;
|
|
||||||
attacker.CheckTalents(AbilityEffectType.OnAttack, attackData);
|
|
||||||
CheckTalents(AbilityEffectType.OnAttacked, attackData);
|
|
||||||
attackData.DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.AttackMultiplier);
|
|
||||||
if (attacker.TeamID == TeamID)
|
|
||||||
{
|
|
||||||
attackData.DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.TeamAttackMultiplier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<Affliction> attackAfflictions;
|
IEnumerable<Affliction> attackAfflictions;
|
||||||
|
|
||||||
if (attackData.Afflictions != null)
|
if (attackData.Afflictions != null)
|
||||||
{
|
{
|
||||||
attackAfflictions = attackData.Afflictions.Union(attack.Afflictions.Keys);
|
attackAfflictions = attackData.Afflictions.Union(attack.Afflictions.Keys);
|
||||||
@@ -4916,10 +4908,21 @@ namespace Barotrauma
|
|||||||
public Character Character { get; set; }
|
public Character Character { get; set; }
|
||||||
public Character Attacker { get; set; }
|
public Character Attacker { get; set; }
|
||||||
|
|
||||||
public AbilityAttackData(Attack sourceAttack, Character character)
|
public AbilityAttackData(Attack sourceAttack, Character target, Character attacker)
|
||||||
{
|
{
|
||||||
SourceAttack = sourceAttack;
|
SourceAttack = sourceAttack;
|
||||||
Character = character;
|
Character = target;
|
||||||
|
if (attacker != null)
|
||||||
|
{
|
||||||
|
Attacker = attacker;
|
||||||
|
attacker.CheckTalents(AbilityEffectType.OnAttack, this);
|
||||||
|
target.CheckTalents(AbilityEffectType.OnAttacked, this);
|
||||||
|
DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.AttackMultiplier);
|
||||||
|
if (attacker.TeamID == target.TeamID)
|
||||||
|
{
|
||||||
|
DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.TeamAttackMultiplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,17 +130,22 @@ namespace Barotrauma
|
|||||||
head = value;
|
head = value;
|
||||||
HeadSprite = null;
|
HeadSprite = null;
|
||||||
AttachmentSprites = null;
|
AttachmentSprites = null;
|
||||||
|
IsMale = value.Preset?.TagSet?.Contains("Male".ToIdentifier()) ?? false;
|
||||||
|
IsFemale = value.Preset?.TagSet?.Contains("Female".ToIdentifier()) ?? false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsMale { get; private set; }
|
||||||
|
|
||||||
|
public bool IsFemale { get; private set; }
|
||||||
|
|
||||||
public CharacterInfoPrefab Prefab => CharacterPrefab.Prefabs[SpeciesName].CharacterInfoPrefab;
|
public CharacterInfoPrefab Prefab => CharacterPrefab.Prefabs[SpeciesName].CharacterInfoPrefab;
|
||||||
public class HeadPreset : ISerializableEntity
|
public class HeadPreset : ISerializableEntity
|
||||||
{
|
{
|
||||||
private readonly CharacterInfoPrefab characterInfoPrefab;
|
private readonly CharacterInfoPrefab characterInfoPrefab;
|
||||||
public Identifier MenuCategory => TagSet.First(t => characterInfoPrefab.VarTags[characterInfoPrefab.MenuCategoryVar].Contains(t));
|
public Identifier MenuCategory => TagSet.First(t => characterInfoPrefab.VarTags[characterInfoPrefab.MenuCategoryVar].Contains(t));
|
||||||
|
|
||||||
|
|
||||||
public ImmutableHashSet<Identifier> TagSet { get; private set; }
|
public ImmutableHashSet<Identifier> TagSet { get; private set; }
|
||||||
|
|
||||||
[Serialize("", IsPropertySaveable.No)]
|
[Serialize("", IsPropertySaveable.No)]
|
||||||
|
|||||||
+3
-3
@@ -71,8 +71,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static Result<ContentFile, string> CreateFromXElement(ContentPackage contentPackage, XElement element)
|
public static Result<ContentFile, string> CreateFromXElement(ContentPackage contentPackage, XElement element)
|
||||||
{
|
{
|
||||||
static Result<ContentFile, string> fail(string error)
|
static Result<ContentFile, string> fail(string error, string? stackTrace = null)
|
||||||
=> Result<ContentFile, string>.Failure(error);
|
=> Result<ContentFile, string>.Failure(error, stackTrace);
|
||||||
|
|
||||||
Identifier elemName = element.NameAsIdentifier();
|
Identifier elemName = element.NameAsIdentifier();
|
||||||
var type = Types.FirstOrDefault(t => t.Names.Contains(elemName));
|
var type = Types.FirstOrDefault(t => t.Names.Contains(elemName));
|
||||||
@@ -99,7 +99,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
return fail($"Failed to load file \"{filePath}\" of type \"{elemName}\": {e.Message}\n{e.StackTrace.CleanupStackTrace()}");
|
return fail($"Failed to load file \"{filePath}\" of type \"{elemName}\": {e.Message}", e.StackTrace.CleanupStackTrace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -34,7 +34,15 @@ namespace Barotrauma
|
|||||||
else if (MatchesSingular(elemName))
|
else if (MatchesSingular(elemName))
|
||||||
{
|
{
|
||||||
T prefab = CreatePrefab(parentElement);
|
T prefab = CreatePrefab(parentElement);
|
||||||
prefabs.Add(prefab, overriding);
|
try
|
||||||
|
{
|
||||||
|
prefabs.Add(prefab, overriding);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
prefab.Dispose(); //clean up before rethrowing, since some prefab types might lock resources
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (MatchesPlural(elemName))
|
else if (MatchesPlural(elemName))
|
||||||
{
|
{
|
||||||
|
|||||||
+22
-4
@@ -1,6 +1,6 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Steam;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@@ -9,7 +9,6 @@ using System.Security.Cryptography;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Steam;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -39,7 +38,7 @@ namespace Barotrauma
|
|||||||
public readonly DateTime? InstallTime;
|
public readonly DateTime? InstallTime;
|
||||||
|
|
||||||
public readonly ImmutableArray<ContentFile> Files;
|
public readonly ImmutableArray<ContentFile> Files;
|
||||||
public readonly ImmutableArray<string> Errors;
|
public readonly ImmutableArray<(string error, string? stackTrace)> Errors;
|
||||||
|
|
||||||
public async Task<bool> IsUpToDate()
|
public async Task<bool> IsUpToDate()
|
||||||
{
|
{
|
||||||
@@ -92,7 +91,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Errors = fileResults
|
Errors = fileResults
|
||||||
.OfType<Failure<ContentFile, string>>()
|
.OfType<Failure<ContentFile, string>>()
|
||||||
.Select(f => f.Error)
|
.Select(f => (f.Error, f.StackTrace))
|
||||||
.ToImmutableArray();
|
.ToImmutableArray();
|
||||||
|
|
||||||
HasMultiplayerSyncedContent = Files.Any(f => !f.NotSyncedInMultiplayer);
|
HasMultiplayerSyncedContent = Files.Any(f => !f.NotSyncedInMultiplayer);
|
||||||
@@ -304,5 +303,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
return path == LocalModsDir;
|
return path == LocalModsDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LogErrors()
|
||||||
|
{
|
||||||
|
if (Errors.Any())
|
||||||
|
{
|
||||||
|
DebugConsole.AddWarning(
|
||||||
|
$"The following errors occurred while loading the content package\"{Name}\". The package might not work correctly.\n" +
|
||||||
|
string.Join('\n', Errors.Select(e => errorToStr(e.error, e.stackTrace))));
|
||||||
|
static string errorToStr(string error, string? stackTrace)
|
||||||
|
{
|
||||||
|
string str = error;
|
||||||
|
if (stackTrace != null)
|
||||||
|
{
|
||||||
|
str += '\n' + stackTrace;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
-3
@@ -430,9 +430,9 @@ namespace Barotrauma
|
|||||||
public static void LoadVanillaFileList()
|
public static void LoadVanillaFileList()
|
||||||
{
|
{
|
||||||
VanillaCorePackage = new CorePackage(XDocument.Load(VanillaFileList), VanillaFileList);
|
VanillaCorePackage = new CorePackage(XDocument.Load(VanillaFileList), VanillaFileList);
|
||||||
foreach (string error in VanillaCorePackage.Errors)
|
foreach ((string error, string? stackTrace) in VanillaCorePackage.Errors)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError(error);
|
DebugConsole.ThrowError(error + (stackTrace == null ? string.Empty : '\n' + stackTrace));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +469,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
var corePackageElement = contentPackagesElement.GetChildElement(CorePackageElementName);
|
var corePackageElement = contentPackagesElement.GetChildElement(CorePackageElementName);
|
||||||
enabledCorePackage = findPackage(CorePackages, corePackageElement) ?? VanillaCorePackage!;
|
var configEnabledCorePackage = findPackage(CorePackages, corePackageElement);
|
||||||
|
if (configEnabledCorePackage == null)
|
||||||
|
{
|
||||||
|
string packageStr = corePackageElement.GetAttributeString("name", null) ?? corePackageElement.GetAttributeStringUnrestricted("path", "UNKNOWN");
|
||||||
|
DebugConsole.ThrowError($"Could not find the selected core package \"{packageStr}\". Switching to the \"{enabledCorePackage.Name}\" package.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enabledCorePackage = configEnabledCorePackage;
|
||||||
|
}
|
||||||
|
|
||||||
var regularPackagesElement = contentPackagesElement.GetChildElement(RegularPackagesElementName);
|
var regularPackagesElement = contentPackagesElement.GetChildElement(RegularPackagesElementName);
|
||||||
if (regularPackagesElement != null)
|
if (regularPackagesElement != null)
|
||||||
@@ -499,5 +508,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
yield return new LoadProgress(1.0f);
|
yield return new LoadProgress(1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LogEnabledRegularPackageErrors()
|
||||||
|
{
|
||||||
|
foreach (var p in EnabledPackages.Regular)
|
||||||
|
{
|
||||||
|
p.LogErrors();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1562,17 +1562,24 @@ namespace Barotrauma
|
|||||||
commands.Add(new Command("money", "money [amount] [character]: Gives the specified amount of money to the crew when a campaign is active.", args =>
|
commands.Add(new Command("money", "money [amount] [character]: Gives the specified amount of money to the crew when a campaign is active.", args =>
|
||||||
{
|
{
|
||||||
if (args.Length == 0) { return; }
|
if (args.Length == 0) { return; }
|
||||||
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
|
|
||||||
|
if (!(GameMain.GameSession?.GameMode is CampaignMode campaign)) { return; }
|
||||||
|
Character targetCharacter = null;
|
||||||
|
|
||||||
|
if (args.Length >= 2)
|
||||||
{
|
{
|
||||||
if (int.TryParse(args[0], out int money))
|
targetCharacter = FindMatchingCharacter(args.Skip(1).ToArray());
|
||||||
{
|
}
|
||||||
campaign.Bank.Give(money);
|
|
||||||
GameAnalyticsManager.AddMoneyGainedEvent(money, GameAnalyticsManager.MoneySource.Cheat, "console");
|
if (int.TryParse(args[0], out int money))
|
||||||
}
|
{
|
||||||
else
|
Wallet wallet = targetCharacter is null || GameMain.IsSingleplayer ? campaign.Bank : targetCharacter.Wallet;
|
||||||
{
|
wallet.Give(money);
|
||||||
ThrowError($"\"{args[0]}\" is not a valid numeric value.");
|
GameAnalyticsManager.AddMoneyGainedEvent(money, GameAnalyticsManager.MoneySource.Cheat, "console");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ThrowError($"\"{args[0]}\" is not a valid numeric value.");
|
||||||
}
|
}
|
||||||
}, isCheat: true, getValidArgs: () => new []
|
}, isCheat: true, getValidArgs: () => new []
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Barotrauma.Extensions;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Barotrauma.Extensions;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -33,11 +31,11 @@ namespace Barotrauma
|
|||||||
public static int GrimeSpriteCount { get; private set; } = 0;
|
public static int GrimeSpriteCount { get; private set; } = 0;
|
||||||
|
|
||||||
public static readonly PrefabCollection<GrimeSprite> GrimeSprites = new PrefabCollection<GrimeSprite>(
|
public static readonly PrefabCollection<GrimeSprite> GrimeSprites = new PrefabCollection<GrimeSprite>(
|
||||||
onAdd: (sprite, b) => GrimeSpriteCount = Math.Max(GrimeSpriteCount, sprite.IndexInFile+1),
|
onAdd: (sprite, b) => GrimeSpriteCount = Math.Max(GrimeSpriteCount, sprite.IndexInFile + 1),
|
||||||
onRemove: (s) =>
|
onRemove: (s) =>
|
||||||
GrimeSpriteCount = GrimeSprites.AllPrefabs
|
GrimeSpriteCount = GrimeSprites.AllPrefabs
|
||||||
.SelectMany(kvp => kvp.Value)
|
.SelectMany(kvp => kvp.Value)
|
||||||
.Where(p => p != s).Select(p => p.IndexInFile+1).MaxOrNull() ?? 0,
|
.Where(p => p != s).Select(p => p.IndexInFile + 1).MaxOrNull() ?? 0,
|
||||||
onSort: null, onAddOverrideFile: null, onRemoveOverrideFile: null);
|
onSort: null, onAddOverrideFile: null, onRemoveOverrideFile: null);
|
||||||
|
|
||||||
public static void LoadFromFile(DecalsFile configFile)
|
public static void LoadFromFile(DecalsFile configFile)
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace Barotrauma
|
|||||||
item.GetComponent<PowerContainer>() != null ||
|
item.GetComponent<PowerContainer>() != null ||
|
||||||
item.GetComponent<Reactor>() != null)
|
item.GetComponent<Reactor>() != null)
|
||||||
{
|
{
|
||||||
item.Indestructible = true;
|
item.InvulnerableToDamage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,6 +210,13 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetOwnerLogName() => Owner switch
|
||||||
|
{
|
||||||
|
Some<Character> { Value: var character } => character.Name,
|
||||||
|
None<Character> _ => "the bank",
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(Owner))
|
||||||
|
};
|
||||||
|
|
||||||
partial void SettingsChanged(Option<int> balanceChanged, Option<int> rewardChanged);
|
partial void SettingsChanged(Option<int> balanceChanged, Option<int> rewardChanged);
|
||||||
|
|
||||||
private static int ClampBalance(int value) => Math.Clamp(value, 0, CampaignMode.MaxMoney);
|
private static int ClampBalance(int value) => Math.Clamp(value, 0, CampaignMode.MaxMoney);
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ namespace Barotrauma
|
|||||||
var campaign = SinglePlayerCampaign.Load(subElement);
|
var campaign = SinglePlayerCampaign.Load(subElement);
|
||||||
campaign.LoadNewLevel();
|
campaign.LoadNewLevel();
|
||||||
GameMode = campaign;
|
GameMode = campaign;
|
||||||
|
InitOwnedSubs(submarineInfo, ownedSubmarines);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case "multiplayercampaign":
|
case "multiplayercampaign":
|
||||||
@@ -156,13 +157,13 @@ namespace Barotrauma
|
|||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||||
{
|
{
|
||||||
mpCampaign.LoadNewLevel();
|
mpCampaign.LoadNewLevel();
|
||||||
|
InitOwnedSubs(submarineInfo, ownedSubmarines);
|
||||||
//save to ensure the campaign ID in the save file matches the one that got assigned to this campaign instance
|
//save to ensure the campaign ID in the save file matches the one that got assigned to this campaign instance
|
||||||
SaveUtil.SaveGame(saveFile);
|
SaveUtil.SaveGame(saveFile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InitOwnedSubs(submarineInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitOwnedSubs(SubmarineInfo submarineInfo, List<SubmarineInfo>? ownedSubmarines = null)
|
private void InitOwnedSubs(SubmarineInfo submarineInfo, List<SubmarineInfo>? ownedSubmarines = null)
|
||||||
@@ -409,14 +410,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GameMain.NetworkMember?.ServerSettings?.LockAllDefaultWires ?? false)
|
if (GameMain.NetworkMember?.ServerSettings?.LockAllDefaultWires ?? false)
|
||||||
{
|
{
|
||||||
foreach (Item item in Item.ItemList)
|
List<Item> items = new List<Item>();
|
||||||
|
items.AddRange(Submarine.MainSubs[0].GetItems(alsoFromConnectedSubs: true));
|
||||||
|
if (Submarine.MainSubs[1] != null)
|
||||||
{
|
{
|
||||||
if (item.Submarine == Submarine.MainSubs[0] ||
|
items.AddRange(Submarine.MainSubs[1].GetItems(alsoFromConnectedSubs: true));
|
||||||
(Submarine.MainSubs[1] != null && item.Submarine == Submarine.MainSubs[1]))
|
}
|
||||||
{
|
foreach (Item item in items)
|
||||||
Wire wire = item.GetComponent<Wire>();
|
{
|
||||||
if (wire != null && !wire.NoAutoLock && wire.Connections.Any(c => c != null)) { wire.Locked = true; }
|
Wire wire = item.GetComponent<Wire>();
|
||||||
}
|
if (wire != null && !wire.NoAutoLock && wire.Connections.Any(c => c != null)) { wire.Locked = true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -228,9 +228,12 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (MathUtils.GetLineRectangleIntersection(ConvertUnits.ToDisplayUnits(sourcePos), ConvertUnits.ToDisplayUnits(rayStart), item.CurrentHull.Rect, out Vector2 hullIntersection))
|
if (MathUtils.GetLineRectangleIntersection(ConvertUnits.ToDisplayUnits(sourcePos), ConvertUnits.ToDisplayUnits(rayStart), item.CurrentHull.Rect, out Vector2 hullIntersection))
|
||||||
{
|
{
|
||||||
Vector2 rayDir = rayStart.NearlyEquals(sourcePos) ? Vector2.Zero : Vector2.Normalize(rayStart - sourcePos);
|
if (!item.CurrentHull.ConnectedGaps.Any(g => g.Open > 0.0f && Submarine.RectContains(g.Rect, hullIntersection)))
|
||||||
rayStartWorld = ConvertUnits.ToSimUnits(hullIntersection - rayDir * 5.0f);
|
{
|
||||||
if (item.Submarine != null) { rayStartWorld += item.Submarine.SimPosition; }
|
Vector2 rayDir = rayStart.NearlyEquals(sourcePos) ? Vector2.Zero : Vector2.Normalize(rayStart - sourcePos);
|
||||||
|
rayStartWorld = ConvertUnits.ToSimUnits(hullIntersection - rayDir * 5.0f);
|
||||||
|
if (item.Submarine != null) { rayStartWorld += item.Submarine.SimPosition; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (HiddenInGame) { return false; }
|
||||||
if (character != null && character.IsOnPlayerTeam)
|
if (character != null && character.IsOnPlayerTeam)
|
||||||
{
|
{
|
||||||
return IsPlayerTeamInteractable;
|
return IsPlayerTeamInteractable;
|
||||||
@@ -1438,7 +1438,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool HasAccess(Character character)
|
public bool HasAccess(Character character)
|
||||||
{
|
{
|
||||||
if (HiddenInGame) { return false; }
|
|
||||||
if (character.IsBot && IgnoreByAI(character)) { return false; }
|
if (character.IsBot && IgnoreByAI(character)) { return false; }
|
||||||
if (!IsInteractable(character)) { return false; }
|
if (!IsInteractable(character)) { return false; }
|
||||||
var itemContainer = GetComponent<ItemContainer>();
|
var itemContainer = GetComponent<ItemContainer>();
|
||||||
@@ -1834,10 +1833,29 @@ namespace Barotrauma
|
|||||||
Submarine prevSub = Submarine;
|
Submarine prevSub = Submarine;
|
||||||
|
|
||||||
var projectile = GetComponent<Projectile>();
|
var projectile = GetComponent<Projectile>();
|
||||||
if (projectile?.StickTarget?.UserData is Limb limb && limb.character != null)
|
if (projectile?.StickTarget != null)
|
||||||
{
|
{
|
||||||
Submarine = body.Submarine = limb.character.Submarine;
|
if (projectile?.StickTarget.UserData is Limb limb && limb.character != null)
|
||||||
currentHull = limb.character.CurrentHull;
|
{
|
||||||
|
Submarine = body.Submarine = limb.character.Submarine;
|
||||||
|
currentHull = limb.character.CurrentHull;
|
||||||
|
}
|
||||||
|
else if (projectile.StickTarget.UserData is Structure structure)
|
||||||
|
{
|
||||||
|
Submarine = body.Submarine = structure.Submarine;
|
||||||
|
currentHull = Hull.FindHull(WorldPosition, CurrentHull);
|
||||||
|
}
|
||||||
|
else if (projectile.StickTarget.UserData is Item targetItem)
|
||||||
|
{
|
||||||
|
Submarine = body.Submarine = targetItem.Submarine;
|
||||||
|
currentHull = targetItem.CurrentHull;
|
||||||
|
}
|
||||||
|
else if (projectile.StickTarget.UserData is Submarine)
|
||||||
|
{
|
||||||
|
//attached to a sub from the outside -> don't move inside the sub
|
||||||
|
Submarine = body.Submarine = null;
|
||||||
|
currentHull = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
displayRange *= 1.0f + sourceItem.GetQualityModifier(Quality.StatType.ExplosionRadius);
|
displayRange *= 1.0f + sourceItem.GetQualityModifier(Quality.StatType.ExplosionRadius);
|
||||||
Attack.DamageMultiplier *= 1.0f + sourceItem.GetQualityModifier(Quality.StatType.ExplosionDamage);
|
Attack.DamageMultiplier *= 1.0f + sourceItem.GetQualityModifier(Quality.StatType.ExplosionDamage);
|
||||||
|
Attack.SourceItem ??= sourceItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 cameraPos = GameMain.GameScreen.Cam.Position;
|
Vector2 cameraPos = GameMain.GameScreen.Cam.Position;
|
||||||
@@ -337,11 +338,17 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AbilityAttackData attackData = new AbilityAttackData(Attack, c, attacker);
|
||||||
|
if (attackData.Afflictions != null)
|
||||||
|
{
|
||||||
|
modifiedAfflictions.AddRange(attackData.Afflictions);
|
||||||
|
}
|
||||||
|
|
||||||
//use a position slightly from the limb's position towards the explosion
|
//use a position slightly from the limb's position towards the explosion
|
||||||
//ensures that the attack hits the correct limb and that the direction of the hit can be determined correctly in the AddDamage methods
|
//ensures that the attack hits the correct limb and that the direction of the hit can be determined correctly in the AddDamage methods
|
||||||
Vector2 dir = worldPosition - limb.WorldPosition;
|
Vector2 dir = worldPosition - limb.WorldPosition;
|
||||||
Vector2 hitPos = limb.WorldPosition + (dir.LengthSquared() <= 0.001f ? Rand.Vector(1.0f) : Vector2.Normalize(dir)) * 0.01f;
|
Vector2 hitPos = limb.WorldPosition + (dir.LengthSquared() <= 0.001f ? Rand.Vector(1.0f) : Vector2.Normalize(dir)) * 0.01f;
|
||||||
AttackResult attackResult = c.AddDamage(hitPos, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker, damageMultiplier: attack.DamageMultiplier);
|
AttackResult attackResult = c.AddDamage(hitPos, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker, damageMultiplier: attack.DamageMultiplier * attackData.DamageMultiplier);
|
||||||
damages.Add(limb, attackResult.Damage);
|
damages.Add(limb, attackResult.Damage);
|
||||||
|
|
||||||
if (attack.StatusEffects != null && attack.StatusEffects.Any())
|
if (attack.StatusEffects != null && attack.StatusEffects.Any())
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ namespace Barotrauma
|
|||||||
public readonly Vector2 Noise;
|
public readonly Vector2 Noise;
|
||||||
public readonly Color DirtColor;
|
public readonly Color DirtColor;
|
||||||
|
|
||||||
|
#if CLIENT
|
||||||
|
public Sprite GrimeSprite;
|
||||||
|
#endif
|
||||||
|
|
||||||
public float ColorStrength
|
public float ColorStrength
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -51,6 +55,9 @@ namespace Barotrauma
|
|||||||
PerlinNoise.GetPerlin(Rect.Y / 1000.0f + 0.5f, Rect.X / 1000.0f + 0.5f));
|
PerlinNoise.GetPerlin(Rect.Y / 1000.0f + 0.5f, Rect.X / 1000.0f + 0.5f));
|
||||||
|
|
||||||
Color = DirtColor = Color.Lerp(new Color(10, 10, 10, 100), new Color(54, 57, 28, 200), Noise.X);
|
Color = DirtColor = Color.Lerp(new Color(10, 10, 10, 100), new Color(54, 57, 28, 200), Noise.X);
|
||||||
|
#if CLIENT
|
||||||
|
GrimeSprite = DecalManager.GrimeSprites[$"{nameof(GrimeSprite)}{index % DecalManager.GrimeSpriteCount}"].Sprite;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public BackgroundSection(Rectangle rect, ushort index, float colorStrength, Color color, ushort rowIndex)
|
public BackgroundSection(Rectangle rect, ushort index, float colorStrength, Color color, ushort rowIndex)
|
||||||
@@ -68,6 +75,9 @@ namespace Barotrauma
|
|||||||
PerlinNoise.GetPerlin(Rect.Y / 1000.0f + 0.5f, Rect.X / 1000.0f + 0.5f));
|
PerlinNoise.GetPerlin(Rect.Y / 1000.0f + 0.5f, Rect.X / 1000.0f + 0.5f));
|
||||||
|
|
||||||
DirtColor = Color.Lerp(new Color(10, 10, 10, 100), new Color(54, 57, 28, 200), Noise.X);
|
DirtColor = Color.Lerp(new Color(10, 10, 10, 100), new Color(54, 57, 28, 200), Noise.X);
|
||||||
|
#if CLIENT
|
||||||
|
GrimeSprite = DecalManager.GrimeSprites[$"{nameof(GrimeSprite)}{index % DecalManager.GrimeSpriteCount}"].Sprite;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetColor(Color color)
|
public bool SetColor(Color color)
|
||||||
@@ -274,33 +284,17 @@ namespace Barotrauma
|
|||||||
get { return Submarine == null ? surface : surface + Submarine.Position.Y; }
|
get { return Submarine == null ? surface : surface + Submarine.Position.Y; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private float dirtiedVolume = 0.0f;
|
|
||||||
|
|
||||||
public float WaterVolume
|
public float WaterVolume
|
||||||
{
|
{
|
||||||
get { return waterVolume; }
|
get { return waterVolume; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (!MathUtils.IsValid(value)) return;
|
if (!MathUtils.IsValid(value)) { return; }
|
||||||
waterVolume = MathHelper.Clamp(value, 0.0f, Volume * MaxCompress);
|
waterVolume = MathHelper.Clamp(value, 0.0f, Volume * MaxCompress);
|
||||||
if (waterVolume < Volume) { Pressure = rect.Y - rect.Height + waterVolume / rect.Width; }
|
if (waterVolume < Volume) { Pressure = rect.Y - rect.Height + waterVolume / rect.Width; }
|
||||||
if (waterVolume > 0.0f)
|
if (waterVolume > 0.0f)
|
||||||
{
|
{
|
||||||
update = true;
|
update = true;
|
||||||
if (BackgroundSections != null)
|
|
||||||
{
|
|
||||||
float volumeMultiplier = Math.Clamp(waterVolume / Volume, 0f, 1f);
|
|
||||||
if (Math.Abs(volumeMultiplier - dirtiedVolume) > 0.075f)
|
|
||||||
{
|
|
||||||
RefreshSubmergedSections(new Rectangle(new Point(0, -rect.Height), new Point(rect.Width, (int)(rect.Height * volumeMultiplier))));
|
|
||||||
dirtiedVolume = volumeMultiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
submergedSections.Clear();
|
|
||||||
dirtiedVolume = 0.0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,8 +385,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly HashSet<int> pendingSectionUpdates = new HashSet<int>();
|
private readonly HashSet<int> pendingSectionUpdates = new HashSet<int>();
|
||||||
|
|
||||||
private readonly List<BackgroundSection> submergedSections = new List<BackgroundSection>();
|
|
||||||
|
|
||||||
public int xBackgroundMax, yBackgroundMax;
|
public int xBackgroundMax, yBackgroundMax;
|
||||||
|
|
||||||
public bool SupportsPaintedColors
|
public bool SupportsPaintedColors
|
||||||
@@ -664,7 +656,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
BackgroundSections?.Clear();
|
BackgroundSections?.Clear();
|
||||||
submergedSections?.Clear();
|
|
||||||
|
|
||||||
List<FireSource> fireSourcesToRemove = new List<FireSource>(FireSources);
|
List<FireSource> fireSourcesToRemove = new List<FireSource>(FireSources);
|
||||||
foreach (FireSource fireSource in fireSourcesToRemove)
|
foreach (FireSource fireSource in fireSourcesToRemove)
|
||||||
@@ -973,12 +964,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//0.016 increase every ~2000 frames = reaches full dirtiness in ~35 minutes
|
|
||||||
if (submergedSections.Count > 0 && Submarine != null && Submarine.Info.Type == SubmarineType.Player && Rand.Int(2000) == 1)
|
|
||||||
{
|
|
||||||
DirtySections(submergedSections, deltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waterVolume < Volume)
|
if (waterVolume < Volume)
|
||||||
{
|
{
|
||||||
LethalPressure -= 10.0f * deltaTime;
|
LethalPressure -= 10.0f * deltaTime;
|
||||||
@@ -1451,17 +1436,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshSubmergedSections(Rectangle waterArea)
|
|
||||||
{
|
|
||||||
if (BackgroundSections == null) { return; }
|
|
||||||
|
|
||||||
submergedSections.Clear();
|
|
||||||
foreach (var section in GetBackgroundSectionsViaContaining(waterArea))
|
|
||||||
{
|
|
||||||
submergedSections.Add(section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool DoesSectionMatch(int index, int row)
|
public bool DoesSectionMatch(int index, int row)
|
||||||
{
|
{
|
||||||
return index >= 0 && row >= 0 && BackgroundSections.Count > index && BackgroundSections[index] != null && BackgroundSections[index].RowIndex == row;
|
return index >= 0 && row >= 0 && BackgroundSections.Count > index && BackgroundSections[index] != null && BackgroundSections[index].RowIndex == row;
|
||||||
@@ -1528,15 +1502,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DirtySections(List<BackgroundSection> sections, float dirtyVal)
|
|
||||||
{
|
|
||||||
if (sections == null) { return; }
|
|
||||||
for (int i = 0; i < sections.Count; i++)
|
|
||||||
{
|
|
||||||
IncreaseSectionColorOrStrength(sections[i], sections[i].DirtColor, dirtyVal, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CleanSection(BackgroundSection section, float cleanVal, bool updateRequired)
|
public void CleanSection(BackgroundSection section, float cleanVal, bool updateRequired)
|
||||||
{
|
{
|
||||||
bool decalsCleaned = false;
|
bool decalsCleaned = false;
|
||||||
|
|||||||
@@ -38,9 +38,13 @@ namespace Barotrauma.RuinGeneration
|
|||||||
NewLineOnAttributes = true
|
NewLineOnAttributes = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IEnumerable<ContentPackage> packages = ContentPackageManager.LocalPackages;
|
||||||
|
#if DEBUG
|
||||||
|
packages = packages.Union(ContentPackageManager.VanillaCorePackage.ToEnumerable());
|
||||||
|
#endif
|
||||||
foreach (RuinGenerationParams generationParams in RuinParams)
|
foreach (RuinGenerationParams generationParams in RuinParams)
|
||||||
{
|
{
|
||||||
foreach (RuinConfigFile configFile in ContentPackageManager.AllPackages.SelectMany(p => p.GetFiles<RuinConfigFile>()))
|
foreach (RuinConfigFile configFile in packages.SelectMany(p => p.GetFiles<RuinConfigFile>()))
|
||||||
{
|
{
|
||||||
if (configFile.Path != generationParams.ContentFile.Path) { continue; }
|
if (configFile.Path != generationParams.ContentFile.Path) { continue; }
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -15,14 +13,18 @@ namespace Barotrauma
|
|||||||
Structure = 1,
|
Structure = 1,
|
||||||
Decorative = 2,
|
Decorative = 2,
|
||||||
Machine = 4,
|
Machine = 4,
|
||||||
Equipment = 8,
|
Medical = 8,
|
||||||
Electrical = 16,
|
Weapon = 16,
|
||||||
Material = 32,
|
Diving = 32,
|
||||||
Misc = 64,
|
Equipment = 64,
|
||||||
Alien = 128,
|
Fuel = 128,
|
||||||
Wrecked = 256,
|
Electrical = 256,
|
||||||
ItemAssembly = 512,
|
Material = 1024,
|
||||||
Legacy = 1024
|
Alien = 2048,
|
||||||
|
Wrecked = 4096,
|
||||||
|
ItemAssembly = 8192,
|
||||||
|
Legacy = 16384,
|
||||||
|
Misc = 32768
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract partial class MapEntityPrefab : PrefabWithUintIdentifier
|
abstract partial class MapEntityPrefab : PrefabWithUintIdentifier
|
||||||
|
|||||||
@@ -1540,8 +1540,10 @@ namespace Barotrauma
|
|||||||
List<HumanPrefab> killedCharacters = new List<HumanPrefab>();
|
List<HumanPrefab> killedCharacters = new List<HumanPrefab>();
|
||||||
List<(HumanPrefab HumanPrefab, CharacterInfo CharacterInfo)> selectedCharacters
|
List<(HumanPrefab HumanPrefab, CharacterInfo CharacterInfo)> selectedCharacters
|
||||||
= new List<(HumanPrefab HumanPrefab, CharacterInfo CharacterInfo)>();
|
= new List<(HumanPrefab HumanPrefab, CharacterInfo CharacterInfo)>();
|
||||||
foreach (HumanPrefab humanPrefab in outpost.Info.OutpostGenerationParams.GetHumanPrefabs(Rand.RandSync.ServerAndClient))
|
var humanPrefabs = outpost.Info.OutpostGenerationParams.GetHumanPrefabs(Rand.RandSync.ServerAndClient);
|
||||||
|
foreach (HumanPrefab humanPrefab in humanPrefabs)
|
||||||
{
|
{
|
||||||
|
if (humanPrefab is null) { continue; }
|
||||||
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.ServerAndClient), randSync: Rand.RandSync.ServerAndClient);
|
var characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobOrJobPrefab: humanPrefab.GetJobPrefab(Rand.RandSync.ServerAndClient), randSync: Rand.RandSync.ServerAndClient);
|
||||||
if (location != null && location.KilledCharacterIdentifiers.Contains(characterInfo.GetIdentifier()))
|
if (location != null && location.KilledCharacterIdentifiers.Contains(characterInfo.GetIdentifier()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Name = TextManager.GetWithVariable("wreckeditemformat", "[name]", Name);
|
Name = TextManager.GetWithVariable("wreckeditemformat", "[name]", Name);
|
||||||
}
|
}
|
||||||
|
Name = Name.Fallback(OriginalName);
|
||||||
|
|
||||||
var tags = new HashSet<Identifier>();
|
var tags = new HashSet<Identifier>();
|
||||||
string joinedTags = element.GetAttributeString("tags", "");
|
string joinedTags = element.GetAttributeString("tags", "");
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasPermissions = false;
|
public bool HasPermissions => Permissions != ClientPermissions.None;
|
||||||
|
|
||||||
public VoipQueue VoipQueue
|
public VoipQueue VoipQueue
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace Barotrauma.Networking
|
|||||||
Wiring,
|
Wiring,
|
||||||
ServerMessage,
|
ServerMessage,
|
||||||
ConsoleUsage,
|
ConsoleUsage,
|
||||||
|
Money,
|
||||||
Karma,
|
Karma,
|
||||||
Talent,
|
Talent,
|
||||||
Error,
|
Error,
|
||||||
@@ -53,9 +54,10 @@ namespace Barotrauma.Networking
|
|||||||
{ MessageType.Wiring, new Color(255, 157, 85) },
|
{ MessageType.Wiring, new Color(255, 157, 85) },
|
||||||
{ MessageType.ServerMessage, new Color(157, 225, 160) },
|
{ MessageType.ServerMessage, new Color(157, 225, 160) },
|
||||||
{ MessageType.ConsoleUsage, new Color(0, 162, 232) },
|
{ MessageType.ConsoleUsage, new Color(0, 162, 232) },
|
||||||
|
{ MessageType.Money, Color.Green },
|
||||||
{ MessageType.Karma, new Color(75, 88, 255) },
|
{ MessageType.Karma, new Color(75, 88, 255) },
|
||||||
{ MessageType.Talent, new Color(125, 125, 255) },
|
{ MessageType.Talent, new Color(125, 125, 255) },
|
||||||
{ MessageType.Error, Color.Red },
|
{ MessageType.Error, Color.Red }
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Dictionary<MessageType, string> messageTypeName = new Dictionary<MessageType, string>
|
private readonly Dictionary<MessageType, string> messageTypeName = new Dictionary<MessageType, string>
|
||||||
@@ -68,6 +70,7 @@ namespace Barotrauma.Networking
|
|||||||
{ MessageType.Wiring, "Wiring" },
|
{ MessageType.Wiring, "Wiring" },
|
||||||
{ MessageType.ServerMessage, "ServerMessage" },
|
{ MessageType.ServerMessage, "ServerMessage" },
|
||||||
{ MessageType.ConsoleUsage, "ConsoleUsage" },
|
{ MessageType.ConsoleUsage, "ConsoleUsage" },
|
||||||
|
{ MessageType.Money, "Money" },
|
||||||
{ MessageType.Karma, "Karma" },
|
{ MessageType.Karma, "Karma" },
|
||||||
{ MessageType.Talent, "Talent" },
|
{ MessageType.Talent, "Talent" },
|
||||||
{ MessageType.Error, "Error" }
|
{ MessageType.Error, "Error" }
|
||||||
|
|||||||
@@ -1007,6 +1007,19 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (attributeName == "move")
|
||||||
|
{
|
||||||
|
Vector2 moveAmount = subElement.GetAttributeVector2("move", Vector2.Zero);
|
||||||
|
if (entity is Structure structure)
|
||||||
|
{
|
||||||
|
structure.Move(moveAmount);
|
||||||
|
}
|
||||||
|
else if (entity is Item item)
|
||||||
|
{
|
||||||
|
item.Move(moveAmount);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (entity.SerializableProperties.TryGetValue(attributeName, out SerializableProperty property))
|
if (entity.SerializableProperties.TryGetValue(attributeName, out SerializableProperty property))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -148,6 +148,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public struct GraphicsSettings
|
public struct GraphicsSettings
|
||||||
{
|
{
|
||||||
|
public static readonly Point MinSupportedResolution = new Point(1024, 540);
|
||||||
|
|
||||||
public static GraphicsSettings GetDefault()
|
public static GraphicsSettings GetDefault()
|
||||||
{
|
{
|
||||||
GraphicsSettings gfxSettings = new GraphicsSettings
|
GraphicsSettings gfxSettings = new GraphicsSettings
|
||||||
|
|||||||
@@ -167,16 +167,9 @@ namespace Barotrauma
|
|||||||
var type = Type;
|
var type = Type;
|
||||||
if (type == ConditionType.Uncertain)
|
if (type == ConditionType.Uncertain)
|
||||||
{
|
{
|
||||||
if (AfflictionPrefab.Prefabs.ContainsKey(AttributeName))
|
type = AfflictionPrefab.Prefabs.ContainsKey(AttributeName)
|
||||||
{
|
? ConditionType.Affliction
|
||||||
type = ConditionType.Affliction;
|
: ConditionType.PropertyValue;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
type = (target?.SerializableProperties?.ContainsKey(AttributeName) ?? false)
|
|
||||||
? ConditionType.PropertyValue
|
|
||||||
: ConditionType.HasSpecifierTag;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkContained)
|
if (checkContained)
|
||||||
@@ -250,6 +243,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Operator == OperatorType.Equals ? matches >= SplitAttributeValue.Length : matches <= 0;
|
return Operator == OperatorType.Equals ? matches >= SplitAttributeValue.Length : matches <= 0;
|
||||||
|
case ConditionType.HasSpecifierTag:
|
||||||
|
{
|
||||||
|
if (target == null) { return Operator == OperatorType.NotEquals; }
|
||||||
|
if (!(target is Character { Info: { } characterInfo })) { return false; }
|
||||||
|
|
||||||
|
return (Operator == OperatorType.Equals) ==
|
||||||
|
SplitAttributeValue.All(v => characterInfo.Head.Preset.TagSet.Contains(v));
|
||||||
|
}
|
||||||
case ConditionType.SpeciesName:
|
case ConditionType.SpeciesName:
|
||||||
{
|
{
|
||||||
if (target == null) { return Operator == OperatorType.NotEquals; }
|
if (target == null) { return Operator == OperatorType.NotEquals; }
|
||||||
|
|||||||
@@ -309,6 +309,11 @@ namespace Barotrauma.Steam
|
|||||||
|
|
||||||
XDocument fileListSrc = XMLExtensions.TryLoadXml(Path.Combine(itemDirectory, ContentPackage.FileListFileName));
|
XDocument fileListSrc = XMLExtensions.TryLoadXml(Path.Combine(itemDirectory, ContentPackage.FileListFileName));
|
||||||
string modName = fileListSrc.Root.GetAttributeString("name", item.Title).Trim();
|
string modName = fileListSrc.Root.GetAttributeString("name", item.Title).Trim();
|
||||||
|
string[] modPathSplit = fileListSrc.Root.GetAttributeString("path", "")
|
||||||
|
.CleanUpPathCrossPlatform(correctFilenameCase: false).Split("/");
|
||||||
|
string? modPathDirName = modPathSplit.Length > 1 && modPathSplit[0] == "Mods"
|
||||||
|
? modPathSplit[1]
|
||||||
|
: null;
|
||||||
string modVersion = fileListSrc.Root.GetAttributeString("modversion", ContentPackage.DefaultModVersion);
|
string modVersion = fileListSrc.Root.GetAttributeString("modversion", ContentPackage.DefaultModVersion);
|
||||||
Version gameVersion = fileListSrc.Root.GetAttributeVersion("gameversion", GameMain.Version);
|
Version gameVersion = fileListSrc.Root.GetAttributeVersion("gameversion", GameMain.Version);
|
||||||
bool isCorePackage = fileListSrc.Root.GetAttributeBool("corepackage", false);
|
bool isCorePackage = fileListSrc.Root.GetAttributeBool("corepackage", false);
|
||||||
@@ -316,7 +321,7 @@ namespace Barotrauma.Steam
|
|||||||
|
|
||||||
using (var copyIndicator = new CopyIndicator(copyIndicatorPath))
|
using (var copyIndicator = new CopyIndicator(copyIndicatorPath))
|
||||||
{
|
{
|
||||||
await CopyDirectory(itemDirectory, modName, itemDirectory, installDir);
|
await CopyDirectory(itemDirectory, modPathDirName ?? modName, itemDirectory, installDir);
|
||||||
|
|
||||||
string fileListDestPath = Path.Combine(installDir, ContentPackage.FileListFileName);
|
string fileListDestPath = Path.Combine(installDir, ContentPackage.FileListFileName);
|
||||||
XDocument fileListDest = XMLExtensions.TryLoadXml(fileListDestPath);
|
XDocument fileListDest = XMLExtensions.TryLoadXml(fileListDestPath);
|
||||||
@@ -330,9 +335,9 @@ namespace Barotrauma.Steam
|
|||||||
new XAttribute("modversion", modVersion),
|
new XAttribute("modversion", modVersion),
|
||||||
new XAttribute("gameversion", gameVersion),
|
new XAttribute("gameversion", gameVersion),
|
||||||
new XAttribute("installtime", ToolBox.Epoch.FromDateTime(updateTime)));
|
new XAttribute("installtime", ToolBox.Epoch.FromDateTime(updateTime)));
|
||||||
if (modName.ToIdentifier() != itemTitle)
|
if ((modPathDirName ?? modName).ToIdentifier() != itemTitle)
|
||||||
{
|
{
|
||||||
root.Add(new XAttribute("altnames", modName));
|
root.Add(new XAttribute("altnames", modPathDirName ?? modName));
|
||||||
}
|
}
|
||||||
if (!expectedHash.IsNullOrEmpty())
|
if (!expectedHash.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace Barotrauma
|
|||||||
if (Debugger.IsAttached) { Debugger.Break(); }
|
if (Debugger.IsAttached) { Debugger.Break(); }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return Plain(lStr);
|
return Plain(lStr ?? string.Empty);
|
||||||
}
|
}
|
||||||
public static implicit operator RichString(string str) => (LocalizedString)str;
|
public static implicit operator RichString(string str) => (LocalizedString)str;
|
||||||
|
|
||||||
|
|||||||
@@ -149,22 +149,34 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
for (int i = 0; i < Texts.Count; i++)
|
XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
|
||||||
{
|
if (doc == null) { return; }
|
||||||
Identifier key = Texts.Keys.ElementAt(i);
|
|
||||||
Texts.TryGetValue(key, out ImmutableArray<string> infoList);
|
List<(string key, string value)> texts = new List<(string key, string value)>();
|
||||||
|
|
||||||
|
foreach (var element in doc.Root.Elements())
|
||||||
|
{
|
||||||
|
string text = element.ElementInnerText()
|
||||||
|
.Replace("&", "&")
|
||||||
|
.Replace("<", "<")
|
||||||
|
.Replace(">", ">")
|
||||||
|
.Replace(""", "\"")
|
||||||
|
.Replace("'", "'");
|
||||||
|
|
||||||
|
texts.Add((element.Name.ToString(), text));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ((string key, string value) in texts)
|
||||||
|
{
|
||||||
|
sb.Append(key); // ID
|
||||||
|
sb.Append('*');
|
||||||
|
sb.Append(value); // Original
|
||||||
|
sb.Append('*');
|
||||||
|
// Translated
|
||||||
|
sb.Append('*');
|
||||||
|
// Comments
|
||||||
|
sb.AppendLine();
|
||||||
|
|
||||||
for (int j = 0; j < infoList.Length; j++)
|
|
||||||
{
|
|
||||||
sb.Append(key); // ID
|
|
||||||
sb.Append('*');
|
|
||||||
sb.Append(infoList[j]); // Original
|
|
||||||
sb.Append('*');
|
|
||||||
// Translated
|
|
||||||
sb.Append('*');
|
|
||||||
// Comments
|
|
||||||
sb.AppendLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Barotrauma.IO.File.WriteAllText($"csv_{Language.ToString().ToLower()}_{index}.csv", sb.ToString());
|
Barotrauma.IO.File.WriteAllText($"csv_{Language.ToString().ToLower()}_{index}.csv", sb.ToString());
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ namespace Barotrauma
|
|||||||
public static Success<T, TError> Success(T value)
|
public static Success<T, TError> Success(T value)
|
||||||
=> new Success<T, TError>(value);
|
=> new Success<T, TError>(value);
|
||||||
|
|
||||||
public static Failure<T, TError> Failure(TError error)
|
public static Failure<T, TError> Failure(TError error, string? stackTrace)
|
||||||
=> new Failure<T, TError>(error);
|
=> new Failure<T, TError>(error, stackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class Success<T, TError> : Result<T, TError>
|
public sealed class Success<T, TError> : Result<T, TError>
|
||||||
@@ -33,11 +33,15 @@ namespace Barotrauma
|
|||||||
where TError: notnull
|
where TError: notnull
|
||||||
{
|
{
|
||||||
public readonly TError Error;
|
public readonly TError Error;
|
||||||
|
|
||||||
|
public readonly string? StackTrace;
|
||||||
|
|
||||||
public override bool IsSuccess => false;
|
public override bool IsSuccess => false;
|
||||||
|
|
||||||
public Failure(TError error)
|
public Failure(TError error, string? stackTrace)
|
||||||
{
|
{
|
||||||
Error = error;
|
Error = error;
|
||||||
|
StackTrace = stackTrace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
namespace Barotrauma.IO
|
namespace Barotrauma.IO
|
||||||
{
|
{
|
||||||
@@ -23,9 +24,15 @@ namespace Barotrauma.IO
|
|||||||
|
|
||||||
public static bool CanWrite(string path, bool isDirectory)
|
public static bool CanWrite(string path, bool isDirectory)
|
||||||
{
|
{
|
||||||
path = System.IO.Path.GetFullPath(path).CleanUpPath();
|
string getFullPath(string p)
|
||||||
string localModsDir = System.IO.Path.GetFullPath(ContentPackage.LocalModsDir).CleanUpPath();
|
=> System.IO.Path.GetFullPath(p).CleanUpPath();
|
||||||
string workshopModsDir = System.IO.Path.GetFullPath(ContentPackage.WorkshopModsDir).CleanUpPath();
|
|
||||||
|
path = getFullPath(path);
|
||||||
|
string localModsDir = getFullPath(ContentPackage.LocalModsDir);
|
||||||
|
string workshopModsDir = getFullPath(ContentPackage.WorkshopModsDir);
|
||||||
|
#if CLIENT
|
||||||
|
string tempDownloadDir = getFullPath(ModReceiver.DownloadFolder);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!isDirectory)
|
if (!isDirectory)
|
||||||
{
|
{
|
||||||
@@ -34,8 +41,15 @@ namespace Barotrauma.IO
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!path.StartsWith(workshopModsDir, StringComparison.OrdinalIgnoreCase)
|
|
||||||
&& !path.StartsWith(localModsDir, StringComparison.OrdinalIgnoreCase)
|
bool pathStartsWith(string prefix)
|
||||||
|
=> path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
if (!pathStartsWith(workshopModsDir)
|
||||||
|
&& !pathStartsWith(localModsDir)
|
||||||
|
#if CLIENT
|
||||||
|
&& !pathStartsWith(tempDownloadDir)
|
||||||
|
#endif
|
||||||
&& (extension == ".dll" || extension == ".exe" || extension == ".json"))
|
&& (extension == ".dll" || extension == ".exe" || extension == ".json"))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
partial class SaveUtil
|
static class SaveUtil
|
||||||
{
|
{
|
||||||
private static readonly string LegacySaveFolder = Path.Combine("Data", "Saves");
|
private static readonly string LegacySaveFolder = Path.Combine("Data", "Saves");
|
||||||
private static readonly string LegacyMultiplayerSaveFolder = Path.Combine(LegacySaveFolder, "Multiplayer");
|
private static readonly string LegacyMultiplayerSaveFolder = Path.Combine(LegacySaveFolder, "Multiplayer");
|
||||||
|
|||||||
Binary file not shown.
@@ -1,3 +1,58 @@
|
|||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.17.7.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Water no longer dirties up walls.
|
||||||
|
- New store (and sub editor) categories: weapon, medical, diving, and fuel. Reorganized the items into categories.
|
||||||
|
- Disabled store category buttons for categories that contain no items.
|
||||||
|
|
||||||
|
Changes (unstable only):
|
||||||
|
- Content package errors are logged in the debug console when enabling a mod that has errors, + listed in tooltips in the Mods tab.
|
||||||
|
- Updated sprites for the wallet related features.
|
||||||
|
- Personal wallet balance now shows in the bottom right character portrait.
|
||||||
|
- Latcher: new sounds and minor tweaks.
|
||||||
|
|
||||||
|
Fixes (unstable only):
|
||||||
|
- Fixed crashing when pressing the "retry" button in the pause menu when the outpost store interface is open.
|
||||||
|
- Fixed crashing when opening the Mods tab when not connected to Steam.
|
||||||
|
- Fixed structures not using the name defined in xml when the name can't be found in loca files.
|
||||||
|
- Fixed inability to start additional votes when another vote is running.
|
||||||
|
- Fixed buying from outpost vendors requiring sell permissions.
|
||||||
|
- Fixed clients with the ManagePermissions being able to edit the host's permissions (didn't actually do anything, but the menu still showed up).
|
||||||
|
- Fixed inability to repair beacon station devices after the beacon is activated.
|
||||||
|
- Fixed tiny plus/minus buttons in spawnpoint editing menu.
|
||||||
|
- Fixed vomiting sounds not playing.
|
||||||
|
- Fixed some mods failing to extract after being downloaded from the server.
|
||||||
|
- Fixed crashing when deleting a Workshop item that has music-related errors.
|
||||||
|
- Fixed submarine editor listing recently disabled subs in the Load menu.
|
||||||
|
- Fixed certain old mods not having their paths corrected properly when installed through the Workshop or transferred from the Mods folder.
|
||||||
|
- Optimized file transfers.
|
||||||
|
- Disabled unsupported resolutions in the settings menu.
|
||||||
|
- Fixed crashing in event editor when loading prefabs or projects.
|
||||||
|
- Fixed ping and wallet columns switching places in tab menu when a character dies.
|
||||||
|
- Fixed "Lots!" text appearing too eagerly when playing on lower resolutions.
|
||||||
|
- Fixed monsters using fast swim parameters when they swim slowly.
|
||||||
|
- Fixed human head sometimes shaking while aiming.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Fixed occasional performance dips when spineling spikes get stuck to the sub's exterior walls.
|
||||||
|
- Fixed item assemblies getting misaligned with the grid after saving.
|
||||||
|
- Fixed "Shell A 18" not aligning with the other shell pieces.
|
||||||
|
- Fixed "Deep Sea Slayer" talent not affecting explosive harpoons.
|
||||||
|
- Fixed welding tool's, plasma cutter's and watering can's particle effects getting "clamped" to the edges of the hull they're inside.
|
||||||
|
- Fixed permission icon in the client list not updating mid-round.
|
||||||
|
- Fixed "lock default wires" server setting not affecting docked subs.
|
||||||
|
- Fixed Dugong's small pumps working without power.
|
||||||
|
- Fixed buttons in structure editing menu using a different style than other types of entities in the sub editor.
|
||||||
|
- Fixed items flagged as "HiddenInGame" being considered interactable and therefore e.g. valid repair targets.
|
||||||
|
- Fixed some (hopefully for good) issues bots still had with ladders.
|
||||||
|
- Fixed outpost guards not arresting the offender when it's very far from them.
|
||||||
|
- Fixed bots sometimes failing to navigate back to the sub (when they are on the other side of the sub than where the hatch is).
|
||||||
|
|
||||||
|
Modding:
|
||||||
|
- Level editor no longer attempts to save the vanilla content.
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.17.6.0
|
v0.17.6.0
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
@@ -105,6 +160,8 @@ Fixes (unstable only):
|
|||||||
- Fixed flashlights emitting sparks.
|
- Fixed flashlights emitting sparks.
|
||||||
- Flipped the confirm and reset buttons in wallet UI.
|
- Flipped the confirm and reset buttons in wallet UI.
|
||||||
- Added a new column to multiplayer tab menu that shows the amount of money the player has in their wallet.
|
- Added a new column to multiplayer tab menu that shows the amount of money the player has in their wallet.
|
||||||
|
- Added psychosis and hallucination reduction to pipe tobacco, cigars and ethanol, rather than just giving psychosis resistance.
|
||||||
|
- Reduced base price of tobacco products (pipe tobacco and cigars)
|
||||||
|
|
||||||
Modding:
|
Modding:
|
||||||
- Option to make missions force a ruin in the level if there isn't one.
|
- Option to make missions force a ruin in the level if there isn't one.
|
||||||
|
|||||||
@@ -188,6 +188,14 @@ namespace Steamworks
|
|||||||
public static Action<ulong> GlobalOnItemInstalled;
|
public static Action<ulong> GlobalOnItemInstalled;
|
||||||
|
|
||||||
public static uint NumSubscribedItems { get { return Internal.GetNumSubscribedItems(); } }
|
public static uint NumSubscribedItems { get { return Internal.GetNumSubscribedItems(); } }
|
||||||
|
|
||||||
|
public static PublishedFileId[] GetSubscribedItems()
|
||||||
|
{
|
||||||
|
uint numSubscribed = NumSubscribedItems;
|
||||||
|
PublishedFileId[] ids = new PublishedFileId[numSubscribed];
|
||||||
|
Internal.GetSubscribedItems(ids, numSubscribed);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user