This commit is contained in:
@@ -52,7 +52,7 @@ body:
|
|||||||
label: Version
|
label: Version
|
||||||
description: Which version of the game did the bug happen in? You can see the current version number in the bottom left corner of your screen in the main menu.
|
description: Which version of the game did the bug happen in? You can see the current version number in the bottom left corner of your screen in the main menu.
|
||||||
options:
|
options:
|
||||||
- 0.19.11.0
|
- 0.19.14.0
|
||||||
- Other
|
- Other
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Barotrauma
|
|||||||
private PlayerBalanceElement? playerBalanceElement;
|
private PlayerBalanceElement? playerBalanceElement;
|
||||||
|
|
||||||
private List<CharacterInfo> PendingHires => campaign.Map?.CurrentLocation?.HireManager?.PendingHires;
|
private List<CharacterInfo> PendingHires => campaign.Map?.CurrentLocation?.HireManager?.PendingHires;
|
||||||
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign(ClientPermissions.ManageHires);
|
private bool HasPermission => CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageHires);
|
||||||
|
|
||||||
private Point resolutionWhenCreated;
|
private Point resolutionWhenCreated;
|
||||||
|
|
||||||
|
|||||||
@@ -139,8 +139,8 @@ namespace Barotrauma
|
|||||||
return tab switch
|
return tab switch
|
||||||
{
|
{
|
||||||
StoreTab.Buy => true,
|
StoreTab.Buy => true,
|
||||||
StoreTab.Sell => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.SellInventoryItems),
|
StoreTab.Sell => CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.SellInventoryItems),
|
||||||
StoreTab.SellSub => campaignUI.Campaign.AllowedToManageCampaign(Networking.ClientPermissions.SellSubItems),
|
StoreTab.SellSub => CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.SellSubItems),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1867,10 +1867,13 @@ namespace Barotrauma
|
|||||||
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), nameLayout.RectTransform), job.Name, font: GUIStyle.SmallFont) { TextColor = job.Prefab.UIColor };
|
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), nameLayout.RectTransform), job.Name, font: GUIStyle.SmallFont) { TextColor = job.Prefab.UIColor };
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalizedString traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), info.PersonalityTrait.DisplayName);
|
if (info.PersonalityTrait != null)
|
||||||
Vector2 traitSize = GUIStyle.SmallFont.MeasureString(traitString);
|
{
|
||||||
GUITextBlock traitBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), traitString, font: GUIStyle.SmallFont);
|
LocalizedString traitString = TextManager.AddPunctuation(':', TextManager.Get("PersonalityTrait"), info.PersonalityTrait.DisplayName);
|
||||||
traitBlock.RectTransform.NonScaledSize = traitSize.Pad(traitBlock.Padding).ToPoint();
|
Vector2 traitSize = GUIStyle.SmallFont.MeasureString(traitString);
|
||||||
|
GUITextBlock traitBlock = new GUITextBlock(new RectTransform(Vector2.One, nameLayout.RectTransform), traitString, font: GUIStyle.SmallFont);
|
||||||
|
traitBlock.RectTransform.NonScaledSize = traitSize.Pad(traitBlock.Padding).ToPoint();
|
||||||
|
}
|
||||||
|
|
||||||
IEnumerable<TalentPrefab> talentsOutsideTree = info.GetUnlockedTalentsOutsideTree().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
|
IEnumerable<TalentPrefab> talentsOutsideTree = info.GetUnlockedTalentsOutsideTree().Select(e => TalentPrefab.TalentPrefabs.Find(c => c.Identifier == e));
|
||||||
if (talentsOutsideTree.Count() > 0)
|
if (talentsOutsideTree.Count() > 0)
|
||||||
|
|||||||
@@ -847,7 +847,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (UpgradePrefab prefab in prefabs)
|
foreach (UpgradePrefab prefab in prefabs)
|
||||||
{
|
{
|
||||||
if (prefab.MaxLevel is 0) { continue; }
|
if (prefab.GetMaxLevelForCurrentSub() == 0) { continue; }
|
||||||
CreateUpgradeEntry(prefab, category, parent.Content, submarine, entitiesOnSub);
|
CreateUpgradeEntry(prefab, category, parent.Content, submarine, entitiesOnSub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1080,7 +1080,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static GUIFrame CreateUpgradeFrame(UpgradePrefab prefab, UpgradeCategory category, CampaignMode campaign, RectTransform rectTransform, bool addBuyButton = true)
|
public static GUIFrame CreateUpgradeFrame(UpgradePrefab prefab, UpgradeCategory category, CampaignMode campaign, RectTransform rectTransform, bool addBuyButton = true)
|
||||||
{
|
{
|
||||||
int price = prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
|
int price = prefab.Price.GetBuyPrice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
|
||||||
return CreateUpgradeEntry(rectTransform, prefab.Sprite, prefab.Name, prefab.Description, price, new CategoryData(category, prefab), addBuyButton, upgradePrefab: prefab, currentLevel: campaign.UpgradeManager.GetUpgradeLevel(prefab, category));
|
return CreateUpgradeEntry(rectTransform, prefab.Sprite, prefab.Name, prefab.Description, price, new CategoryData(category, prefab), addBuyButton, upgradePrefab: prefab, currentLevel: campaign.UpgradeManager.GetUpgradeLevel(prefab, category));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1177,11 +1177,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private static void UpdateUpgradePercentageText(GUITextBlock text, UpgradePrefab upgradePrefab, int currentLevel)
|
private static void UpdateUpgradePercentageText(GUITextBlock text, UpgradePrefab upgradePrefab, int currentLevel)
|
||||||
{
|
{
|
||||||
float nextIncrease = upgradePrefab.IncreaseOnTooltip * (Math.Min(currentLevel + 1, upgradePrefab.MaxLevel));
|
int maxLevel = upgradePrefab.GetMaxLevelForCurrentSub();
|
||||||
|
float nextIncrease = upgradePrefab.IncreaseOnTooltip * Math.Min(currentLevel + 1, maxLevel);
|
||||||
if (nextIncrease != 0f)
|
if (nextIncrease != 0f)
|
||||||
{
|
{
|
||||||
text.Text = $"{Math.Round(nextIncrease, 1)} %";
|
text.Text = $"{Math.Round(nextIncrease, 1)} %";
|
||||||
if (currentLevel == upgradePrefab.MaxLevel)
|
if (currentLevel == maxLevel)
|
||||||
{
|
{
|
||||||
text.TextColor = Color.Gray;
|
text.TextColor = Color.Gray;
|
||||||
}
|
}
|
||||||
@@ -1221,7 +1222,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
LocalizedString promptBody = TextManager.GetWithVariables("Upgrades.PurchasePromptBody",
|
LocalizedString promptBody = TextManager.GetWithVariables("Upgrades.PurchasePromptBody",
|
||||||
("[upgradename]", prefab.Name),
|
("[upgradename]", prefab.Name),
|
||||||
("[amount]", prefab.Price.GetBuyprice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation).ToString()));
|
("[amount]", prefab.Price.GetBuyPrice(Campaign.UpgradeManager.GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation).ToString()));
|
||||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
||||||
{
|
{
|
||||||
if (GameMain.NetworkMember != null)
|
if (GameMain.NetworkMember != null)
|
||||||
@@ -1617,14 +1618,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int currentLevel = campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
|
int currentLevel = campaign.UpgradeManager.GetUpgradeLevel(prefab, category);
|
||||||
|
|
||||||
LocalizedString progressText = TextManager.GetWithVariables("upgrades.progressformat", ("[level]", currentLevel.ToString()), ("[maxlevel]", prefab.MaxLevel.ToString()));
|
int maxLevel = prefab.GetMaxLevelForCurrentSub();
|
||||||
|
LocalizedString progressText = TextManager.GetWithVariables("upgrades.progressformat", ("[level]", currentLevel.ToString()), ("[maxlevel]", maxLevel.ToString()));
|
||||||
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
|
if (prefabFrame.FindChild("progressbar", true) is { } progressParent)
|
||||||
{
|
{
|
||||||
GUIProgressBar bar = progressParent.GetChild<GUIProgressBar>();
|
GUIProgressBar bar = progressParent.GetChild<GUIProgressBar>();
|
||||||
if (bar != null)
|
if (bar != null)
|
||||||
{
|
{
|
||||||
bar.BarSize = currentLevel / (float) prefab.MaxLevel;
|
bar.BarSize = currentLevel / (float)maxLevel;
|
||||||
bar.Color = currentLevel >= prefab.MaxLevel ? GUIStyle.Green : GUIStyle.Orange;
|
bar.Color = currentLevel >= maxLevel ? GUIStyle.Green : GUIStyle.Orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUITextBlock block = progressParent.GetChild<GUITextBlock>();
|
GUITextBlock block = progressParent.GetChild<GUITextBlock>();
|
||||||
@@ -1637,12 +1639,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUITextBlock priceLabel = textBlocks[0];
|
GUITextBlock priceLabel = textBlocks[0];
|
||||||
priceLabel.Visible = true;
|
priceLabel.Visible = true;
|
||||||
int price = prefab.Price.GetBuyprice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
|
int price = prefab.Price.GetBuyPrice(campaign.UpgradeManager.GetUpgradeLevel(prefab, category), campaign.Map?.CurrentLocation);
|
||||||
|
|
||||||
if (priceLabel != null && !WaitForServerUpdate)
|
if (priceLabel != null && !WaitForServerUpdate)
|
||||||
{
|
{
|
||||||
priceLabel.Text = TextManager.FormatCurrency(price);
|
priceLabel.Text = TextManager.FormatCurrency(price);
|
||||||
if (currentLevel >= prefab.MaxLevel)
|
if (currentLevel >= maxLevel)
|
||||||
{
|
{
|
||||||
priceLabel.Text = TextManager.Get("Upgrade.MaxedUpgrade");
|
priceLabel.Text = TextManager.Get("Upgrade.MaxedUpgrade");
|
||||||
}
|
}
|
||||||
@@ -1651,7 +1653,7 @@ namespace Barotrauma
|
|||||||
GUIButton button = buttonParent.GetChild<GUIButton>();
|
GUIButton button = buttonParent.GetChild<GUIButton>();
|
||||||
if (button != null)
|
if (button != null)
|
||||||
{
|
{
|
||||||
button.Enabled = currentLevel < prefab.MaxLevel;
|
button.Enabled = currentLevel < maxLevel;
|
||||||
if (WaitForServerUpdate || campaign.GetBalance() < price)
|
if (WaitForServerUpdate || campaign.GetBalance() < price)
|
||||||
{
|
{
|
||||||
button.Enabled = false;
|
button.Enabled = false;
|
||||||
@@ -1697,13 +1699,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (GUIComponent component in indicators.Children)
|
foreach (GUIComponent component in indicators.Children)
|
||||||
{
|
{
|
||||||
if (!(component is GUIImage image)) { continue; }
|
if (component is not GUIImage image) { continue; }
|
||||||
|
|
||||||
foreach (UpgradePrefab prefab in prefabs)
|
foreach (UpgradePrefab prefab in prefabs)
|
||||||
{
|
{
|
||||||
if (component.UserData != prefab) { continue; }
|
if (component.UserData != prefab) { continue; }
|
||||||
|
|
||||||
if (prefab.MaxLevel is 0)
|
int maxLevel = prefab.GetMaxLevelForCurrentSub();
|
||||||
|
if (maxLevel == 0)
|
||||||
{
|
{
|
||||||
component.Visible = false;
|
component.Visible = false;
|
||||||
continue;
|
continue;
|
||||||
@@ -1715,7 +1718,6 @@ namespace Barotrauma
|
|||||||
GUIComponentStyle onStyle = styles["upgradeindicatoron".ToIdentifier()];
|
GUIComponentStyle onStyle = styles["upgradeindicatoron".ToIdentifier()];
|
||||||
GUIComponentStyle dimStyle = styles["upgradeindicatordim".ToIdentifier()];
|
GUIComponentStyle dimStyle = styles["upgradeindicatordim".ToIdentifier()];
|
||||||
GUIComponentStyle offStyle = styles["upgradeindicatoroff".ToIdentifier()];
|
GUIComponentStyle offStyle = styles["upgradeindicatoroff".ToIdentifier()];
|
||||||
int maxLevel = prefab.MaxLevel;
|
|
||||||
|
|
||||||
if (maxLevel == 0)
|
if (maxLevel == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// There is a server-side implementation of the method in <see cref="MultiPlayerCampaign"/>
|
/// There is a server-side implementation of the method in <see cref="MultiPlayerCampaign"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AllowedToManageCampaign(ClientPermissions permissions)
|
public static bool AllowedToManageCampaign(ClientPermissions permissions)
|
||||||
{
|
{
|
||||||
//allow managing the round if the client has permissions, is the owner, the only client in the server,
|
//allow managing the round if the client has permissions, is the owner, the only client in the server,
|
||||||
//or if no-one has management permissions
|
//or if no-one has management permissions
|
||||||
@@ -99,7 +99,8 @@ namespace Barotrauma
|
|||||||
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign) ||
|
GameMain.Client.HasPermission(ClientPermissions.ManageCampaign) ||
|
||||||
GameMain.Client.ConnectedClients.Count == 1 ||
|
GameMain.Client.ConnectedClients.Count == 1 ||
|
||||||
GameMain.Client.IsServerOwner ||
|
GameMain.Client.IsServerOwner ||
|
||||||
GameMain.Client.ConnectedClients.None(c => c.InGame && (c.IsOwner || c.HasPermission(permissions)));
|
//allow managing if no-one with permissions is alive
|
||||||
|
GameMain.Client.ConnectedClients.None(c => c.InGame && c.Character is { IsIncapacitated: false, IsDead: false } && (c.IsOwner || c.HasPermission(permissions)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool AllowedToManageWallets()
|
public static bool AllowedToManageWallets()
|
||||||
|
|||||||
@@ -265,6 +265,8 @@ namespace Barotrauma.Items.Components
|
|||||||
foreach (DeconstructItem deconstructItem in it.Prefab.DeconstructItems)
|
foreach (DeconstructItem deconstructItem in it.Prefab.DeconstructItems)
|
||||||
{
|
{
|
||||||
if (!deconstructItem.IsValidDeconstructor(item)) { continue; }
|
if (!deconstructItem.IsValidDeconstructor(item)) { continue; }
|
||||||
|
float percentageHealth = it.Condition / it.MaxCondition;
|
||||||
|
if (percentageHealth < deconstructItem.MinCondition || percentageHealth > deconstructItem.MaxCondition) { continue; }
|
||||||
RegisterItem(deconstructItem.ItemIdentifier, deconstructItem.Amount);
|
RegisterItem(deconstructItem.ItemIdentifier, deconstructItem.Amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1028,7 +1028,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
foreach (var c in MineralClusters)
|
foreach (var c in MineralClusters)
|
||||||
{
|
{
|
||||||
var unobtainedMinerals = c.resources.Where(i => i != null && i.GetRootInventoryOwner() == i);
|
var unobtainedMinerals = c.resources.Where(i => i != null && i.GetComponent<Holdable>() is { Attached: true });
|
||||||
if (unobtainedMinerals.None()) { continue; }
|
if (unobtainedMinerals.None()) { continue; }
|
||||||
if (!CheckResourceMarkerVisibility(c.center, transducerCenter)) { continue; }
|
if (!CheckResourceMarkerVisibility(c.center, transducerCenter)) { continue; }
|
||||||
var i = unobtainedMinerals.FirstOrDefault();
|
var i = unobtainedMinerals.FirstOrDefault();
|
||||||
|
|||||||
@@ -162,23 +162,27 @@ namespace Barotrauma
|
|||||||
|
|
||||||
RemoveFogOfWar(StartLocation);
|
RemoveFogOfWar(StartLocation);
|
||||||
|
|
||||||
GenerateLocationConnectionVisuals();
|
GenerateAllLocationConnectionVisuals();
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void GenerateLocationConnectionVisuals()
|
partial void GenerateAllLocationConnectionVisuals()
|
||||||
{
|
{
|
||||||
foreach (LocationConnection connection in Connections)
|
foreach (LocationConnection connection in Connections)
|
||||||
{
|
{
|
||||||
Vector2 connectionStart = connection.Locations[0].MapPosition;
|
GenerateLocationConnectionVisuals(connection);
|
||||||
Vector2 connectionEnd = connection.Locations[1].MapPosition;
|
|
||||||
float connectionLength = Vector2.Distance(connectionStart, connectionEnd);
|
|
||||||
int iterations = Math.Min((int)Math.Sqrt(connectionLength * generationParams.ConnectionIndicatorIterationMultiplier), 5);
|
|
||||||
connection.CrackSegments.Clear();
|
|
||||||
connection.CrackSegments.AddRange(MathUtils.GenerateJaggedLine(
|
|
||||||
connectionStart, connectionEnd,
|
|
||||||
iterations, connectionLength * generationParams.ConnectionIndicatorDisplacementMultiplier));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
partial void GenerateLocationConnectionVisuals(LocationConnection connection)
|
||||||
|
{
|
||||||
|
Vector2 connectionStart = connection.Locations[0].MapPosition;
|
||||||
|
Vector2 connectionEnd = connection.Locations[1].MapPosition;
|
||||||
|
float connectionLength = Vector2.Distance(connectionStart, connectionEnd);
|
||||||
|
int iterations = Math.Min((int)Math.Sqrt(connectionLength * generationParams.ConnectionIndicatorIterationMultiplier), 5);
|
||||||
|
connection.CrackSegments.Clear();
|
||||||
|
connection.CrackSegments.AddRange(MathUtils.GenerateJaggedLine(
|
||||||
|
connectionStart, connectionEnd,
|
||||||
|
iterations, connectionLength * generationParams.ConnectionIndicatorDisplacementMultiplier));
|
||||||
|
}
|
||||||
|
|
||||||
private void LocationChanged(Location prevLocation, Location newLocation)
|
private void LocationChanged(Location prevLocation, Location newLocation)
|
||||||
{
|
{
|
||||||
@@ -414,7 +418,7 @@ namespace Barotrauma
|
|||||||
new GUIMessageBox(string.Empty, TextManager.Get("LockedPathTooltip"));
|
new GUIMessageBox(string.Empty, TextManager.Get("LockedPathTooltip"));
|
||||||
}
|
}
|
||||||
//clients aren't allowed to select the location without a permission
|
//clients aren't allowed to select the location without a permission
|
||||||
else if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap) ?? false)
|
else if (CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap))
|
||||||
{
|
{
|
||||||
connectionHighlightState = 0.0f;
|
connectionHighlightState = 0.0f;
|
||||||
SelectedConnection = connection;
|
SelectedConnection = connection;
|
||||||
|
|||||||
@@ -702,10 +702,30 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
Enabled = !GameMain.NetworkMember.GameStarted
|
Enabled = !GameMain.NetworkMember.GameStarted
|
||||||
};
|
};
|
||||||
var cargoFrame = new GUIListBox(new RectTransform(new Vector2(0.6f, 0.7f), settingsTabs[(int)SettingsTab.Rounds].RectTransform, Anchor.BottomRight, Pivot.BottomLeft))
|
|
||||||
|
var cargoFrame = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.7f), settingsTabs[(int)SettingsTab.Rounds].RectTransform, Anchor.BottomRight, Pivot.BottomLeft))
|
||||||
{
|
{
|
||||||
Visible = false
|
Visible = false
|
||||||
};
|
};
|
||||||
|
var cargoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), cargoFrame.RectTransform, Anchor.Center))
|
||||||
|
{
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var filterText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), cargoContent.RectTransform), TextManager.Get("serverlog.filter"), font: GUIStyle.SubHeadingFont);
|
||||||
|
var entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), filterText.RectTransform, Anchor.CenterRight), font: GUIStyle.Font, createClearButton: true);
|
||||||
|
filterText.RectTransform.MinSize = new Point(0, entityFilterBox.RectTransform.MinSize.Y);
|
||||||
|
var cargoList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.8f), cargoContent.RectTransform));
|
||||||
|
entityFilterBox.OnTextChanged += (textBox, text) =>
|
||||||
|
{
|
||||||
|
foreach (var child in cargoList.Content.Children)
|
||||||
|
{
|
||||||
|
if (child.UserData is not ItemPrefab itemPrefab) { continue; }
|
||||||
|
child.Visible = string.IsNullOrEmpty(text) || itemPrefab.Name.Contains(text, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
cargoButton.UserData = cargoFrame;
|
cargoButton.UserData = cargoFrame;
|
||||||
cargoButton.OnClicked = (button, obj) =>
|
cargoButton.OnClicked = (button, obj) =>
|
||||||
{
|
{
|
||||||
@@ -721,7 +741,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
GUITextBlock.AutoScaleAndNormalize(buttonHolder.Children.Select(c => ((GUIButton)c).TextBlock));
|
GUITextBlock.AutoScaleAndNormalize(buttonHolder.Children.Select(c => ((GUIButton)c).TextBlock));
|
||||||
|
|
||||||
foreach (ItemPrefab ip in ItemPrefab.Prefabs)
|
foreach (ItemPrefab ip in ItemPrefab.Prefabs.OrderBy(ip => ip.Name))
|
||||||
{
|
{
|
||||||
if (ip.AllowAsExtraCargo.HasValue)
|
if (ip.AllowAsExtraCargo.HasValue)
|
||||||
{
|
{
|
||||||
@@ -732,10 +752,10 @@ namespace Barotrauma.Networking
|
|||||||
if (!ip.CanBeBought) { continue; }
|
if (!ip.CanBeBought) { continue; }
|
||||||
}
|
}
|
||||||
|
|
||||||
var itemFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), cargoFrame.Content.RectTransform) { MinSize = new Point(0, 30) }, isHorizontal: true)
|
var itemFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), cargoList.Content.RectTransform) { MinSize = new Point(0, 30) }, isHorizontal: true)
|
||||||
{
|
{
|
||||||
Stretch = true,
|
Stretch = true,
|
||||||
UserData = cargoFrame,
|
UserData = ip,
|
||||||
RelativeSpacing = 0.05f
|
RelativeSpacing = 0.05f
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -778,7 +798,7 @@ namespace Barotrauma.Networking
|
|||||||
numberInput.IntValue = ExtraCargo.ContainsKey(ip) ? ExtraCargo[ip] : 0;
|
numberInput.IntValue = ExtraCargo.ContainsKey(ip) ? ExtraCargo[ip] : 0;
|
||||||
CoroutineManager.Invoke(() =>
|
CoroutineManager.Invoke(() =>
|
||||||
{
|
{
|
||||||
foreach (var child in cargoFrame.Content.GetAllChildren())
|
foreach (var child in cargoList.Content.GetAllChildren())
|
||||||
{
|
{
|
||||||
if (child.GetChild<GUINumberInput>() is GUINumberInput otherNumberInput)
|
if (child.GetChild<GUINumberInput>() is GUINumberInput otherNumberInput)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ namespace Barotrauma
|
|||||||
foreach (GUITickBox tickBox in missionTickBoxes)
|
foreach (GUITickBox tickBox in missionTickBoxes)
|
||||||
{
|
{
|
||||||
bool disable = hasMaxMissions && !tickBox.Selected;
|
bool disable = hasMaxMissions && !tickBox.Selected;
|
||||||
tickBox.Enabled = Campaign.AllowedToManageCampaign(ClientPermissions.ManageMap) && !disable;
|
tickBox.Enabled = CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap) && !disable;
|
||||||
tickBox.Box.DisabledColor = disable ? tickBox.Box.Color * 0.5f : tickBox.Box.Color * 0.8f;
|
tickBox.Box.DisabledColor = disable ? tickBox.Box.Color * 0.5f : tickBox.Box.Color * 0.8f;
|
||||||
foreach (GUIComponent child in tickBox.Parent.Parent.Children)
|
foreach (GUIComponent child in tickBox.Parent.Parent.Children)
|
||||||
{
|
{
|
||||||
@@ -315,7 +315,7 @@ namespace Barotrauma
|
|||||||
if (GUI.MouseOn == tickBox) { return false; }
|
if (GUI.MouseOn == tickBox) { return false; }
|
||||||
if (tickBox != null)
|
if (tickBox != null)
|
||||||
{
|
{
|
||||||
if (Campaign.AllowedToManageCampaign(ClientPermissions.ManageMap) && tickBox.Enabled)
|
if (CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap) && tickBox.Enabled)
|
||||||
{
|
{
|
||||||
tickBox.Selected = !tickBox.Selected;
|
tickBox.Selected = !tickBox.Selected;
|
||||||
}
|
}
|
||||||
@@ -356,10 +356,10 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
tickBox.RectTransform.MinSize = new Point(tickBox.Rect.Height, 0);
|
tickBox.RectTransform.MinSize = new Point(tickBox.Rect.Height, 0);
|
||||||
tickBox.RectTransform.IsFixedSize = true;
|
tickBox.RectTransform.IsFixedSize = true;
|
||||||
tickBox.Enabled = Campaign.AllowedToManageCampaign(ClientPermissions.ManageMap);
|
tickBox.Enabled = CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap);
|
||||||
tickBox.OnSelected += (GUITickBox tb) =>
|
tickBox.OnSelected += (GUITickBox tb) =>
|
||||||
{
|
{
|
||||||
if (!Campaign.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap)) { return false; }
|
if (!CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap)) { return false; }
|
||||||
|
|
||||||
if (tb.Selected)
|
if (tb.Selected)
|
||||||
{
|
{
|
||||||
@@ -379,7 +379,7 @@ namespace Barotrauma
|
|||||||
UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation));
|
UpdateMaxMissions(connection.OtherLocation(currentDisplayLocation));
|
||||||
|
|
||||||
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
|
if ((Campaign is MultiPlayerCampaign multiPlayerCampaign) && !multiPlayerCampaign.SuppressStateSending &&
|
||||||
Campaign.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap))
|
CampaignMode.AllowedToManageCampaign(Networking.ClientPermissions.ManageMap))
|
||||||
{
|
{
|
||||||
GameMain.Client?.SendCampaignState();
|
GameMain.Client?.SendCampaignState();
|
||||||
}
|
}
|
||||||
@@ -500,7 +500,7 @@ namespace Barotrauma
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
Visible = Campaign.AllowedToManageCampaign(ClientPermissions.ManageMap)
|
Visible = CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap)
|
||||||
};
|
};
|
||||||
|
|
||||||
buttonArea.RectTransform.MinSize = new Point(0, StartButton.RectTransform.MinSize.Y);
|
buttonArea.RectTransform.MinSize = new Point(0, StartButton.RectTransform.MinSize.Y);
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(contentPackageNameElement.Text))
|
if (string.IsNullOrEmpty(contentPackageNameElement.Text))
|
||||||
{
|
{
|
||||||
contentPackageNameElement.Flash();
|
contentPackageNameElement.Flash(useRectangleFlash: true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ContentPackageManager.AllPackages.Any(cp => cp.Name.ToLower() == contentPackageNameElement.Text.ToLower()))
|
if (ContentPackageManager.AllPackages.Any(cp => cp.Name.ToLower() == contentPackageNameElement.Text.ToLower()))
|
||||||
@@ -405,7 +405,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
if (ContentPackage == null)
|
if (ContentPackage == null)
|
||||||
{
|
{
|
||||||
contentPackageDropDown.Flash();
|
contentPackageDropDown.Flash(useRectangleFlash: true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +417,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
if (!File.Exists(evaluatedTexturePath))
|
if (!File.Exists(evaluatedTexturePath))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(GetCharacterEditorTranslation("TextureDoesNotExist"), GUIStyle.Red);
|
GUI.AddMessage(GetCharacterEditorTranslation("TextureDoesNotExist"), GUIStyle.Red);
|
||||||
texturePathElement.Flash(GUIStyle.Red);
|
texturePathElement.Flash(useRectangleFlash: true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,7 +425,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
if (!path.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
|
if (!path.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
GUI.AddMessage(TextManager.Get("WrongFileType"), GUIStyle.Red);
|
GUI.AddMessage(TextManager.Get("WrongFileType"), GUIStyle.Red);
|
||||||
texturePathElement.Flash(GUIStyle.Red);
|
texturePathElement.Flash(useRectangleFlash: true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (IsCopy)
|
if (IsCopy)
|
||||||
@@ -486,7 +486,8 @@ namespace Barotrauma.CharacterEditor
|
|||||||
{
|
{
|
||||||
PlaySoundOnSelect = true,
|
PlaySoundOnSelect = true,
|
||||||
};
|
};
|
||||||
var removeLimbButton = new GUIButton(new RectTransform(new Vector2(0.05f, 1.0f), limbEditLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton")
|
var limbButtonSize = Vector2.One * 0.8f;
|
||||||
|
var removeLimbButton = new GUIButton(new RectTransform(limbButtonSize, limbEditLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton")
|
||||||
{
|
{
|
||||||
OnClicked = (b, d) =>
|
OnClicked = (b, d) =>
|
||||||
{
|
{
|
||||||
@@ -497,7 +498,7 @@ namespace Barotrauma.CharacterEditor
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var addLimbButton = new GUIButton(new RectTransform(new Vector2(0.05f, 1.0f), limbEditLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton")
|
var addLimbButton = new GUIButton(new RectTransform(limbButtonSize, limbEditLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton")
|
||||||
{
|
{
|
||||||
OnClicked = (b, d) =>
|
OnClicked = (b, d) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1817,7 +1817,11 @@ namespace Barotrauma
|
|||||||
subList = dropDown.ListBox.Content;
|
subList = dropDown.ListBox.Content;
|
||||||
}
|
}
|
||||||
|
|
||||||
var frame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.15f), subList.RectTransform) { MinSize = new Point(0, 25) },
|
var frame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), subList.RectTransform)
|
||||||
|
{
|
||||||
|
//enough space for 2 lines (price and class) + some padding
|
||||||
|
MinSize = new Point(0, (int)(GUIStyle.SmallFont.LineHeight * 2.3f))
|
||||||
|
},
|
||||||
style: "ListBoxElement")
|
style: "ListBoxElement")
|
||||||
{
|
{
|
||||||
ToolTip = sub.Description,
|
ToolTip = sub.Description,
|
||||||
|
|||||||
+15
-2
@@ -7,6 +7,8 @@ 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.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
@@ -953,8 +955,19 @@ namespace Barotrauma
|
|||||||
okButton.Enabled = false;
|
okButton.Enabled = false;
|
||||||
okButton.OnClicked = (btn, userdata) =>
|
okButton.OnClicked = (btn, userdata) =>
|
||||||
{
|
{
|
||||||
if (!Endpoint.Parse(endpointBox.Text).TryUnwrap(out var endpoint)) { return false; }
|
if (Endpoint.Parse(endpointBox.Text).TryUnwrap(out var endpoint))
|
||||||
JoinServer(endpoint, "");
|
{
|
||||||
|
JoinServer(endpoint, "");
|
||||||
|
}
|
||||||
|
else if (LidgrenEndpoint.ParseFromWithHostNameCheck(endpointBox.Text, tryParseHostName: true).TryUnwrap(out var lidgrenEndpoint))
|
||||||
|
{
|
||||||
|
JoinServer(lidgrenEndpoint, "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new GUIMessageBox(TextManager.Get("error"), TextManager.GetWithVariable("invalidipaddress", "[serverip]:[port]", endpointBox.Text));
|
||||||
|
endpointBox.Flash();
|
||||||
|
}
|
||||||
msgBox.Close();
|
msgBox.Close();
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1926,9 +1926,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
filePath = $"{ContentPath.ModDirStr}/{filePath[packageDir.Length..]}";
|
filePath = $"{ContentPath.ModDirStr}/{filePath[packageDir.Length..]}";
|
||||||
}
|
}
|
||||||
if (!modProject.Files.Any(f => f.Type == subFileType &&
|
if (!modProject.Files.Any(f => f.Type == subFileType && f.Path == filePath))
|
||||||
f.Path == filePath))
|
|
||||||
{
|
{
|
||||||
|
//check if there's a file with the same name but different filename case
|
||||||
|
var matchingFile = modProject.Files.FirstOrDefault(f => f.Type == subFileType && filePath.CleanUpPath().Equals(f.Path.CleanUpPath(), StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (matchingFile != null)
|
||||||
|
{
|
||||||
|
File.Delete(matchingFile.Path.Replace(ContentPath.ModDirStr, packageDir));
|
||||||
|
modProject.RemoveFile(matchingFile);
|
||||||
|
}
|
||||||
var newFile = ModProject.File.FromPath(filePath, subFileType);
|
var newFile = ModProject.File.FromPath(filePath, subFileType);
|
||||||
modProject.AddFile(newFile);
|
modProject.AddFile(newFile);
|
||||||
}
|
}
|
||||||
@@ -2485,7 +2491,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), tierGroup.RectTransform), NumberType.Int)
|
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), tierGroup.RectTransform), NumberType.Int)
|
||||||
{
|
{
|
||||||
IntValue = SubmarineInfo.GetDefaultTier(MainSub.Info.Price),
|
IntValue = MainSub.Info.Tier,
|
||||||
MinValueInt = 1,
|
MinValueInt = 1,
|
||||||
MaxValueInt = 3,
|
MaxValueInt = 3,
|
||||||
OnValueChanged = (numberInput) =>
|
OnValueChanged = (numberInput) =>
|
||||||
@@ -2827,6 +2833,7 @@ namespace Barotrauma
|
|||||||
OnClicked = (button, o) =>
|
OnClicked = (button, o) =>
|
||||||
{
|
{
|
||||||
var requiredPackages = MapEntity.mapEntityList.Select(e => e.Prefab.ContentPackage)
|
var requiredPackages = MapEntity.mapEntityList.Select(e => e.Prefab.ContentPackage)
|
||||||
|
.Where(cp => cp != null)
|
||||||
.Distinct().OfType<ContentPackage>().Select(p => p.Name).ToHashSet();
|
.Distinct().OfType<ContentPackage>().Select(p => p.Name).ToHashSet();
|
||||||
var tickboxes = requiredContentPackList.Content.Children.OfType<GUITickBox>().ToArray();
|
var tickboxes = requiredContentPackList.Content.Children.OfType<GUITickBox>().ToArray();
|
||||||
tickboxes.ForEach(tb => tb.Selected = requiredPackages.Contains(tb.UserData as string ?? ""));
|
tickboxes.ForEach(tb => tb.Selected = requiredPackages.Contains(tb.UserData as string ?? ""));
|
||||||
@@ -2925,7 +2932,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
subTypeDropdown.SelectItem(MainSub.Info.Type);
|
subTypeDropdown.SelectItem(MainSub.Info.Type);
|
||||||
|
|
||||||
if (quickSave) { SaveSub(null); }
|
if (quickSave) { SaveSub(packageToSaveInList.SelectedData as ContentPackage); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateSaveAssemblyScreen()
|
private void CreateSaveAssemblyScreen()
|
||||||
|
|||||||
@@ -785,13 +785,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OnClicked = (btn, obj) =>
|
OnClicked = (btn, obj) =>
|
||||||
{
|
{
|
||||||
GameSettings.SetCurrentConfig(unsavedConfig);
|
ApplyInstalledModChanges();
|
||||||
if (WorkshopMenu is MutableWorkshopMenu mutableWorkshopMenu &&
|
|
||||||
mutableWorkshopMenu.CurrentTab == MutableWorkshopMenu.Tab.InstalledMods)
|
|
||||||
{
|
|
||||||
mutableWorkshopMenu.Apply();
|
|
||||||
}
|
|
||||||
GameSettings.SaveCurrentConfig();
|
|
||||||
mainFrame.Flash(color: GUIStyle.Green);
|
mainFrame.Flash(color: GUIStyle.Green);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
@@ -804,6 +798,17 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ApplyInstalledModChanges()
|
||||||
|
{
|
||||||
|
GameSettings.SetCurrentConfig(unsavedConfig);
|
||||||
|
if (WorkshopMenu is MutableWorkshopMenu mutableWorkshopMenu &&
|
||||||
|
mutableWorkshopMenu.CurrentTab == MutableWorkshopMenu.Tab.InstalledMods)
|
||||||
|
{
|
||||||
|
mutableWorkshopMenu.Apply();
|
||||||
|
}
|
||||||
|
GameSettings.SaveCurrentConfig();
|
||||||
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
if (GameMain.Client is null || GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled)
|
if (GameMain.Client is null || GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled)
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
angle = targetLimb.body.Rotation + ((targetLimb.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
angle = targetLimb.body.Rotation + ((targetLimb.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||||
particleRotation = -targetLimb.body.Rotation;
|
particleRotation = -targetLimb.body.Rotation;
|
||||||
|
float offset = targetLimb.Params.GetSpriteOrientation() - MathHelper.PiOver2;
|
||||||
|
particleRotation += offset;
|
||||||
if (targetLimb.body.Dir < 0.0f)
|
if (targetLimb.body.Dir < 0.0f)
|
||||||
{
|
{
|
||||||
particleRotation += MathHelper.Pi;
|
particleRotation += MathHelper.Pi;
|
||||||
|
|||||||
@@ -598,13 +598,14 @@ namespace Barotrauma.Steam
|
|||||||
|
|
||||||
bool reinstallAction(GUIButton button, object o)
|
bool reinstallAction(GUIButton button, object o)
|
||||||
{
|
{
|
||||||
|
SettingsMenu.Instance?.ApplyInstalledModChanges();
|
||||||
int prevIndex = ContentPackageManager.EnabledPackages.Regular.IndexOf(contentPackage);
|
int prevIndex = ContentPackageManager.EnabledPackages.Regular.IndexOf(contentPackage);
|
||||||
TaskPool.AddIfNotFound($"Reinstall{workshopItem.Id}",
|
TaskPool.AddIfNotFound($"Reinstall{workshopItem.Id}",
|
||||||
SteamManager.Workshop.Reinstall(workshopItem), t =>
|
SteamManager.Workshop.Reinstall(workshopItem), t =>
|
||||||
{
|
{
|
||||||
ContentPackageManager.WorkshopPackages.Refresh();
|
ContentPackageManager.WorkshopPackages.Refresh();
|
||||||
ContentPackageManager.EnabledPackages.RefreshUpdatedMods();
|
ContentPackageManager.EnabledPackages.RefreshUpdatedMods();
|
||||||
if (SettingsMenu.Instance?.WorkshopMenu is MutableWorkshopMenu mutableWorkshopMenu)
|
if (SettingsMenu.Instance?.WorkshopMenu is MutableWorkshopMenu mutableWorkshopMenu && !mutableWorkshopMenu.ViewingItemDetails)
|
||||||
{
|
{
|
||||||
mutableWorkshopMenu.PopulateInstalledModLists(forceRefreshEnabled: true);
|
mutableWorkshopMenu.PopulateInstalledModLists(forceRefreshEnabled: true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -543,7 +543,8 @@ namespace Barotrauma.Steam
|
|||||||
|
|
||||||
var localModProject = new ModProject(localPackage)
|
var localModProject = new ModProject(localPackage)
|
||||||
{
|
{
|
||||||
UgcId = Option<ContentPackageId>.Some(new SteamWorkshopId(resultId))
|
UgcId = Option<ContentPackageId>.Some(new SteamWorkshopId(resultId)),
|
||||||
|
ModVersion = modVersion
|
||||||
};
|
};
|
||||||
localModProject.DiscardHashAndInstallTime();
|
localModProject.DiscardHashAndInstallTime();
|
||||||
localModProject.Save(localPackage.Path);
|
localModProject.Save(localPackage.Path);
|
||||||
|
|||||||
@@ -11,7 +11,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.19.11.0</Version>
|
<Version>0.19.14.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>
|
||||||
|
|||||||
@@ -11,7 +11,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.19.11.0</Version>
|
<Version>0.19.14.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>
|
||||||
|
|||||||
@@ -11,7 +11,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.19.11.0</Version>
|
<Version>0.19.14.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>
|
||||||
|
|||||||
@@ -11,7 +11,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.19.11.0</Version>
|
<Version>0.19.14.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>
|
||||||
|
|||||||
@@ -11,7 +11,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.19.11.0</Version>
|
<Version>0.19.14.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>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// There is a client-side implementation of the method in <see cref="CampaignMode"/>
|
/// There is a client-side implementation of the method in <see cref="CampaignMode"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AllowedToManageCampaign(Client client, ClientPermissions permissions)
|
public static bool AllowedToManageCampaign(Client client, ClientPermissions permissions)
|
||||||
{
|
{
|
||||||
//allow managing the campaign if the client has permissions, is the owner, or the only client in the server,
|
//allow managing the campaign if the client has permissions, is the owner, or the only client in the server,
|
||||||
//or if no-one has management permissions
|
//or if no-one has management permissions
|
||||||
@@ -25,7 +25,8 @@ namespace Barotrauma
|
|||||||
client.HasPermission(ClientPermissions.ManageCampaign) ||
|
client.HasPermission(ClientPermissions.ManageCampaign) ||
|
||||||
GameMain.Server.ConnectedClients.Count == 1 ||
|
GameMain.Server.ConnectedClients.Count == 1 ||
|
||||||
IsOwner(client) ||
|
IsOwner(client) ||
|
||||||
GameMain.Server.ConnectedClients.None(c => c.InGame && (IsOwner(c) || c.HasPermission(permissions)));
|
//allow managing if no-one with permissions is alive
|
||||||
|
GameMain.Server.ConnectedClients.None(c => c.InGame && c.Character is { IsIncapacitated: false, IsDead: false } && (IsOwner(c) || c.HasPermission(permissions)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AllowedToManageWallets(Client client)
|
public bool AllowedToManageWallets(Client client)
|
||||||
|
|||||||
+1
-1
@@ -1019,7 +1019,7 @@ namespace Barotrauma
|
|||||||
UpgradeManager.PurchaseUpgrade(prefab, category, client: sender);
|
UpgradeManager.PurchaseUpgrade(prefab, category, client: sender);
|
||||||
|
|
||||||
// unstable logging
|
// unstable logging
|
||||||
int price = prefab.Price.GetBuyprice(UpgradeManager.GetUpgradeLevel(prefab, category), Map?.CurrentLocation);
|
int price = prefab.Price.GetBuyPrice(UpgradeManager.GetUpgradeLevel(prefab, category), Map?.CurrentLocation);
|
||||||
int level = UpgradeManager.GetUpgradeLevel(prefab, category);
|
int level = UpgradeManager.GetUpgradeLevel(prefab, category);
|
||||||
GameServer.Log($"SERVER: Purchased level {level} {category.Identifier}.{prefab.Identifier} for {price}", ServerLog.MessageType.ServerMessage);
|
GameServer.Log($"SERVER: Purchased level {level} {category.Identifier}.{prefab.Identifier} for {price}", ServerLog.MessageType.ServerMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
var allowOutpostAutoDocking = (AllowOutpostAutoDocking)msg.ReadByte();
|
var allowOutpostAutoDocking = (AllowOutpostAutoDocking)msg.ReadByte();
|
||||||
if (outpostAutoDockingPromptShown &&
|
if (outpostAutoDockingPromptShown &&
|
||||||
(GameMain.GameSession?.Campaign?.AllowedToManageCampaign(c, ClientPermissions.ManageMap) ?? false))
|
CampaignMode.AllowedToManageCampaign(c, ClientPermissions.ManageMap))
|
||||||
{
|
{
|
||||||
this.allowOutpostAutoDocking = allowOutpostAutoDocking;
|
this.allowOutpostAutoDocking = allowOutpostAutoDocking;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -496,9 +496,18 @@ namespace Barotrauma.Networking
|
|||||||
// -> something wen't wrong during startup, re-enable start button and reset AutoRestartTimer
|
// -> something wen't wrong during startup, re-enable start button and reset AutoRestartTimer
|
||||||
if (startGameCoroutine != null && !CoroutineManager.IsCoroutineRunning(startGameCoroutine))
|
if (startGameCoroutine != null && !CoroutineManager.IsCoroutineRunning(startGameCoroutine))
|
||||||
{
|
{
|
||||||
if (ServerSettings.AutoRestart) ServerSettings.AutoRestartTimer = Math.Max(ServerSettings.AutoRestartInterval, 5.0f);
|
if (ServerSettings.AutoRestart) { ServerSettings.AutoRestartTimer = Math.Max(ServerSettings.AutoRestartInterval, 5.0f); }
|
||||||
//GameMain.NetLobbyScreen.StartButtonEnabled = true;
|
|
||||||
|
|
||||||
|
if (startGameCoroutine.Exception != null && OwnerConnection != null)
|
||||||
|
{
|
||||||
|
SendConsoleMessage(
|
||||||
|
startGameCoroutine.Exception.Message + '\n' +
|
||||||
|
(startGameCoroutine.Exception.StackTrace?.CleanupStackTrace() ?? "null"),
|
||||||
|
connectedClients.Find(c => c.Connection == OwnerConnection),
|
||||||
|
Color.Red);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndGame();
|
||||||
GameMain.NetLobbyScreen.LastUpdateID++;
|
GameMain.NetLobbyScreen.LastUpdateID++;
|
||||||
|
|
||||||
startGameCoroutine = null;
|
startGameCoroutine = null;
|
||||||
@@ -1391,8 +1400,8 @@ namespace Barotrauma.Networking
|
|||||||
if (end)
|
if (end)
|
||||||
{
|
{
|
||||||
if (mpCampaign == null ||
|
if (mpCampaign == null ||
|
||||||
mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageRound) ||
|
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageRound) ||
|
||||||
mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign))
|
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign))
|
||||||
{
|
{
|
||||||
bool save = inc.ReadBoolean();
|
bool save = inc.ReadBoolean();
|
||||||
if (GameStarted)
|
if (GameStarted)
|
||||||
@@ -1422,7 +1431,7 @@ namespace Barotrauma.Networking
|
|||||||
SendDirectChatMessage("Cannot continue the campaign from the previous save (round already running).", sender, ChatMessageType.Error);
|
SendDirectChatMessage("Cannot continue the campaign from the previous save (round already running).", sender, ChatMessageType.Error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageMap))
|
else if (CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageMap))
|
||||||
{
|
{
|
||||||
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
|
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
|
||||||
}
|
}
|
||||||
@@ -1433,7 +1442,7 @@ namespace Barotrauma.Networking
|
|||||||
Log("Client \"" + ClientLogName(sender) + "\" started the round.", ServerLog.MessageType.ServerMessage);
|
Log("Client \"" + ClientLogName(sender) + "\" started the round.", ServerLog.MessageType.ServerMessage);
|
||||||
StartGame();
|
StartGame();
|
||||||
}
|
}
|
||||||
else if (mpCampaign != null && (mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageMap)))
|
else if (mpCampaign != null && (CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageMap)))
|
||||||
{
|
{
|
||||||
var availableTransition = mpCampaign.GetAvailableTransition(out _, out _);
|
var availableTransition = mpCampaign.GetAvailableTransition(out _, out _);
|
||||||
//don't force location if we've teleported
|
//don't force location if we've teleported
|
||||||
@@ -2013,7 +2022,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
//and assume the message was received, so we don't have to keep resending
|
//and assume the message was received, so we don't have to keep resending
|
||||||
//these large initial messages until the client acknowledges receiving them
|
//these large initial messages until the client acknowledges receiving them
|
||||||
c.LastRecvLobbyUpdate++;
|
c.LastRecvLobbyUpdate = GameMain.NetLobbyScreen.LastUpdateID;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2032,7 +2041,7 @@ namespace Barotrauma.Networking
|
|||||||
c.ChatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, c.LastRecvChatMsgID));
|
c.ChatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, c.LastRecvChatMsgID));
|
||||||
for (int i = 0; i < c.ChatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++)
|
for (int i = 0; i < c.ChatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++)
|
||||||
{
|
{
|
||||||
if (outmsg.LengthBytes + c.ChatMsgQueue[i].EstimateLengthBytesServer(c) > MsgConstants.MTU - 5)
|
if (outmsg.LengthBytes + c.ChatMsgQueue[i].EstimateLengthBytesServer(c) > MsgConstants.MTU - 5 && i > 0)
|
||||||
{
|
{
|
||||||
//not enough room in this packet
|
//not enough room in this packet
|
||||||
return;
|
return;
|
||||||
@@ -2616,19 +2625,17 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void EndGame(CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None, bool wasSaved = false)
|
public void EndGame(CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None, bool wasSaved = false)
|
||||||
{
|
{
|
||||||
if (!GameStarted)
|
if (GameStarted)
|
||||||
{
|
{
|
||||||
return;
|
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||||
}
|
{
|
||||||
|
Log("Ending the round...\n" + Environment.StackTrace.CleanupStackTrace(), ServerLog.MessageType.ServerMessage);
|
||||||
|
|
||||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
}
|
||||||
{
|
else
|
||||||
Log("Ending the round...\n" + Environment.StackTrace.CleanupStackTrace(), ServerLog.MessageType.ServerMessage);
|
{
|
||||||
|
Log("Ending the round...", ServerLog.MessageType.ServerMessage);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Log("Ending the round...", ServerLog.MessageType.ServerMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string endMessage = TextManager.FormatServerMessage("RoundSummaryRoundHasEnded");
|
string endMessage = TextManager.FormatServerMessage("RoundSummaryRoundHasEnded");
|
||||||
@@ -2641,7 +2648,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Mission> missions = GameMain.GameSession.Missions.ToList();
|
List<Mission> missions = GameMain.GameSession.Missions.ToList();
|
||||||
if (GameMain.GameSession.IsRunning)
|
if (GameMain.GameSession is { IsRunning: true })
|
||||||
{
|
{
|
||||||
GameMain.GameSession.EndRound(endMessage, traitorResults);
|
GameMain.GameSession.EndRound(endMessage, traitorResults);
|
||||||
}
|
}
|
||||||
@@ -2667,7 +2674,10 @@ namespace Barotrauma.Networking
|
|||||||
c.PositionUpdateLastSent.Clear();
|
c.PositionUpdateLastSent.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
KarmaManager.OnRoundEnded();
|
if (GameStarted)
|
||||||
|
{
|
||||||
|
KarmaManager.OnRoundEnded();
|
||||||
|
}
|
||||||
|
|
||||||
RespawnManager = null;
|
RespawnManager = null;
|
||||||
GameStarted = false;
|
GameStarted = false;
|
||||||
|
|||||||
@@ -11,7 +11,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.19.11.0</Version>
|
<Version>0.19.14.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>
|
||||||
|
|||||||
+2
-2
@@ -186,8 +186,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (character.SelectedItem != Item)
|
if (character.SelectedItem != Item)
|
||||||
{
|
{
|
||||||
if (Item.TryInteract(character, ignoreRequiredItems: true, forceSelectKey: true) ||
|
if (Item.TryInteract(character, ignoreRequiredItems: true, forceUseKey: true) ||
|
||||||
Item.TryInteract(character, ignoreRequiredItems: true, forceUseKey: true))
|
Item.TryInteract(character, ignoreRequiredItems: true, forceSelectKey: true))
|
||||||
{
|
{
|
||||||
character.SelectedItem = Item;
|
character.SelectedItem = Item;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1345,7 +1345,7 @@ namespace Barotrauma
|
|||||||
bool limbsValid = true;
|
bool limbsValid = true;
|
||||||
foreach (Limb limb in limbs)
|
foreach (Limb limb in limbs)
|
||||||
{
|
{
|
||||||
if (limb.body == null || !limb.body.Enabled) { continue; }
|
if (limb?.body == null || !limb.body.Enabled) { continue; }
|
||||||
if (!CheckValidity(limb.body))
|
if (!CheckValidity(limb.body))
|
||||||
{
|
{
|
||||||
limbsValid = false;
|
limbsValid = false;
|
||||||
@@ -1967,7 +1967,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (Limb l in Limbs)
|
foreach (Limb l in Limbs)
|
||||||
{
|
{
|
||||||
l.Remove();
|
l?.Remove();
|
||||||
}
|
}
|
||||||
limbs = null;
|
limbs = null;
|
||||||
}
|
}
|
||||||
@@ -1976,7 +1976,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (PhysicsBody b in collider)
|
foreach (PhysicsBody b in collider)
|
||||||
{
|
{
|
||||||
b.Remove();
|
b?.Remove();
|
||||||
}
|
}
|
||||||
collider = null;
|
collider = null;
|
||||||
}
|
}
|
||||||
@@ -1985,7 +1985,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (var joint in LimbJoints)
|
foreach (var joint in LimbJoints)
|
||||||
{
|
{
|
||||||
var j = joint.Joint;
|
var j = joint?.Joint;
|
||||||
if (GameMain.World.JointList.Contains(j))
|
if (GameMain.World.JointList.Contains(j))
|
||||||
{
|
{
|
||||||
GameMain.World.Remove(j);
|
GameMain.World.Remove(j);
|
||||||
|
|||||||
@@ -2728,6 +2728,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool selectInputSameAsDeselect = false;
|
||||||
|
#if CLIENT
|
||||||
|
selectInputSameAsDeselect = GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Select] == GameSettings.CurrentConfig.KeyMap.Bindings[InputType.Deselect];
|
||||||
|
#endif
|
||||||
|
|
||||||
if (SelectedCharacter != null && (IsKeyHit(InputType.Grab) || IsKeyHit(InputType.Health))) //Let people use ladders and buttons and stuff when dragging chars
|
if (SelectedCharacter != null && (IsKeyHit(InputType.Grab) || IsKeyHit(InputType.Health))) //Let people use ladders and buttons and stuff when dragging chars
|
||||||
{
|
{
|
||||||
DeselectCharacter();
|
DeselectCharacter();
|
||||||
@@ -2767,14 +2772,16 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
FocusedCharacter.onCustomInteract(FocusedCharacter, this);
|
FocusedCharacter.onCustomInteract(FocusedCharacter, this);
|
||||||
}
|
}
|
||||||
else if (IsKeyHit(InputType.Deselect) && SelectedItem != null)
|
else if (IsKeyHit(InputType.Deselect) && SelectedItem != null &&
|
||||||
|
(focusedItem == null || focusedItem == SelectedItem || !selectInputSameAsDeselect))
|
||||||
{
|
{
|
||||||
SelectedItem = null;
|
SelectedItem = null;
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
CharacterHealth.OpenHealthWindow = null;
|
CharacterHealth.OpenHealthWindow = null;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (IsKeyHit(InputType.Deselect) && SelectedSecondaryItem != null)
|
else if (IsKeyHit(InputType.Deselect) && SelectedSecondaryItem != null && SelectedSecondaryItem.GetComponent<Ladder>() == null &&
|
||||||
|
(focusedItem == null || focusedItem == SelectedSecondaryItem || !selectInputSameAsDeselect))
|
||||||
{
|
{
|
||||||
SelectedSecondaryItem = null;
|
SelectedSecondaryItem = null;
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
@@ -2789,6 +2796,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (CharacterInventory.DraggingItemToWorld) { return; }
|
if (CharacterInventory.DraggingItemToWorld) { return; }
|
||||||
|
if (selectInputSameAsDeselect)
|
||||||
|
{
|
||||||
|
keys[(int)InputType.Deselect].Reset();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
bool canInteract = focusedItem.TryInteract(this);
|
bool canInteract = focusedItem.TryInteract(this);
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
|
|||||||
@@ -543,7 +543,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void GetName(Rand.RandSync randSync, out string name)
|
private void GetName(Rand.RandSync randSync, out string name)
|
||||||
{
|
{
|
||||||
var nameElement = CharacterConfigElement.GetChildElement("names") ?? CharacterConfigElement.GetChildElement("name");
|
ContentXElement nameElement = CharacterConfigElement.GetChildElement("names") ?? CharacterConfigElement.GetChildElement("name");
|
||||||
ContentPath namesXmlFile = nameElement?.GetAttributeContentPath("path") ?? ContentPath.Empty;
|
ContentPath namesXmlFile = nameElement?.GetAttributeContentPath("path") ?? ContentPath.Empty;
|
||||||
XElement namesXml = null;
|
XElement namesXml = null;
|
||||||
if (!namesXmlFile.IsNullOrEmpty()) //names.xml is defined
|
if (!namesXmlFile.IsNullOrEmpty()) //names.xml is defined
|
||||||
@@ -554,8 +554,8 @@ namespace Barotrauma
|
|||||||
else //the legacy firstnames.txt/lastnames.txt shit is defined
|
else //the legacy firstnames.txt/lastnames.txt shit is defined
|
||||||
{
|
{
|
||||||
namesXml = new XElement("names", new XAttribute("format", "[firstname] [lastname]"));
|
namesXml = new XElement("names", new XAttribute("format", "[firstname] [lastname]"));
|
||||||
var firstNamesPath = ReplaceVars(nameElement.GetAttributeContentPath("firstname")?.Value ?? "");
|
string firstNamesPath = nameElement == null ? string.Empty : ReplaceVars(nameElement.GetAttributeContentPath("firstname")?.Value ?? "");
|
||||||
var lastNamesPath = ReplaceVars(nameElement.GetAttributeContentPath("lastname")?.Value ?? "");
|
string lastNamesPath = nameElement == null ? string.Empty : ReplaceVars(nameElement.GetAttributeContentPath("lastname")?.Value ?? "");
|
||||||
if (File.Exists(firstNamesPath) && File.Exists(lastNamesPath))
|
if (File.Exists(firstNamesPath) && File.Exists(lastNamesPath))
|
||||||
{
|
{
|
||||||
var firstNames = File.ReadAllLines(firstNamesPath);
|
var firstNames = File.ReadAllLines(firstNamesPath);
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@
|
|||||||
{
|
{
|
||||||
var affliction = character.CharacterHealth.GetAffliction(afflictionIdentifier);
|
var affliction = character.CharacterHealth.GetAffliction(afflictionIdentifier);
|
||||||
if (affliction == null) { return false; }
|
if (affliction == null) { return false; }
|
||||||
return minimumPercentage <= affliction.Strength / affliction.Prefab.MaxStrength;
|
return affliction.Strength >= affliction.Prefab.ActivationThreshold && minimumPercentage <= affliction.Strength / affliction.Prefab.MaxStrength;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -13,21 +13,23 @@ namespace Barotrauma.Abilities
|
|||||||
|
|
||||||
protected override void ApplyEffect()
|
protected override void ApplyEffect()
|
||||||
{
|
{
|
||||||
if (!SelectedItemHasTag(Character)) { return; }
|
if (!SelectedItemHasTag(Character, tag)) { return; }
|
||||||
|
|
||||||
Character closestCharacter = null;
|
Character closestCharacter = null;
|
||||||
float closestDistance = squaredMaxDistance;
|
float closestDistance = squaredMaxDistance;
|
||||||
|
|
||||||
foreach (Character crewCharacter in Character.GetFriendlyCrew(Character))
|
foreach (Character crewCharacter in Character.GetFriendlyCrew(Character))
|
||||||
{
|
{
|
||||||
if (crewCharacter != Character && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(crewCharacter)) is float tempDistance && tempDistance < closestDistance)
|
if (crewCharacter != Character &&
|
||||||
|
Vector2.DistanceSquared(Character.WorldPosition, crewCharacter.WorldPosition) is float tempDistance && tempDistance < closestDistance &&
|
||||||
|
SelectedItemHasTag(crewCharacter, tag))
|
||||||
{
|
{
|
||||||
closestCharacter = crewCharacter;
|
closestCharacter = crewCharacter;
|
||||||
closestDistance = tempDistance;
|
closestDistance = tempDistance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closestCharacter == null || !SelectedItemHasTag(closestCharacter)) { return; }
|
if (closestCharacter == null) { return; }
|
||||||
|
|
||||||
if (closestDistance < squaredMaxDistance)
|
if (closestDistance < squaredMaxDistance)
|
||||||
{
|
{
|
||||||
@@ -35,7 +37,7 @@ namespace Barotrauma.Abilities
|
|||||||
ApplyEffectSpecific(closestCharacter);
|
ApplyEffectSpecific(closestCharacter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SelectedItemHasTag(Character character) =>
|
static bool SelectedItemHasTag(Character character, string tag) =>
|
||||||
(character.SelectedItem != null && character.SelectedItem.HasTag(tag)) ||
|
(character.SelectedItem != null && character.SelectedItem.HasTag(tag)) ||
|
||||||
(character.SelectedSecondaryItem != null && character.SelectedSecondaryItem.HasTag(tag));
|
(character.SelectedSecondaryItem != null && character.SelectedSecondaryItem.HasTag(tag));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Option<ContentPackageId> ugcId = ContentPackageId.Parse(otherModName.Value);
|
Option<ContentPackageId> ugcId = ContentPackageId.Parse(otherModName.Value);
|
||||||
ContentPackage? otherMod =
|
ContentPackage? otherMod =
|
||||||
allPackages.FirstOrDefault(p => ugcId == p.UgcId)
|
allPackages.FirstOrDefault(p => ugcId.IsSome() && ugcId == p.UgcId)
|
||||||
?? allPackages.FirstOrDefault(p => p.Name == otherModName)
|
?? allPackages.FirstOrDefault(p => p.Name == otherModName)
|
||||||
?? allPackages.FirstOrDefault(p => p.NameMatches(otherModName))
|
?? allPackages.FirstOrDefault(p => p.NameMatches(otherModName))
|
||||||
?? throw new MissingContentPackageException(ContentPackage, otherModName.Value);
|
?? throw new MissingContentPackageException(ContentPackage, otherModName.Value);
|
||||||
|
|||||||
@@ -1335,7 +1335,7 @@ namespace Barotrauma
|
|||||||
if (!prefab.UpgradeCategories.Contains(category)) { continue; }
|
if (!prefab.UpgradeCategories.Contains(category)) { continue; }
|
||||||
if (!string.IsNullOrWhiteSpace(prefabIdentifier) && prefab.Identifier != prefabIdentifier) { continue; }
|
if (!string.IsNullOrWhiteSpace(prefabIdentifier) && prefab.Identifier != prefabIdentifier) { continue; }
|
||||||
|
|
||||||
int targetLevel = prefab.MaxLevel - upgradeManager.GetRealUpgradeLevel(prefab, category);
|
int targetLevel = prefab.GetMaxLevelForCurrentSub() - upgradeManager.GetRealUpgradeLevel(prefab, category);
|
||||||
for (int i = 0; i < targetLevel; i++)
|
for (int i = 0; i < targetLevel; i++)
|
||||||
{
|
{
|
||||||
upgradeManager.PurchaseUpgrade(prefab, category, force: true);
|
upgradeManager.PurchaseUpgrade(prefab, category, force: true);
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
|||||||
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
humanPrefab.GiveItems(newCharacter, newCharacter.Submarine);
|
||||||
if (LootingIsStealing)
|
if (LootingIsStealing)
|
||||||
{
|
{
|
||||||
foreach (Item item in newCharacter.Inventory.AllItems)
|
foreach (Item item in newCharacter.Inventory.FindAllItems(recursive: true))
|
||||||
{
|
{
|
||||||
item.SpawnedInCurrentOutpost = true;
|
item.SpawnedInCurrentOutpost = true;
|
||||||
item.AllowStealing = false;
|
item.AllowStealing = false;
|
||||||
|
|||||||
@@ -273,13 +273,13 @@ namespace Barotrauma
|
|||||||
IsCampaignSet = element.GetAttributeBool("campaign", LevelType == LevelData.LevelType.Outpost || (parentSet?.IsCampaignSet ?? false));
|
IsCampaignSet = element.GetAttributeBool("campaign", LevelType == LevelData.LevelType.Outpost || (parentSet?.IsCampaignSet ?? false));
|
||||||
ResetTime = element.GetAttributeFloat("resettime", 0);
|
ResetTime = element.GetAttributeFloat("resettime", 0);
|
||||||
|
|
||||||
DefaultCommonness = 1.0f;
|
DefaultCommonness = element.GetAttributeFloat("commonness", 1.0f);
|
||||||
foreach (var subElement in element.Elements())
|
foreach (var subElement in element.Elements())
|
||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "commonness":
|
case "commonness":
|
||||||
DefaultCommonness = subElement.GetAttributeFloat("commonness", 0.0f);
|
DefaultCommonness = subElement.GetAttributeFloat("commonness", DefaultCommonness);
|
||||||
foreach (XElement overrideElement in subElement.Elements())
|
foreach (XElement overrideElement in subElement.Elements())
|
||||||
{
|
{
|
||||||
if (overrideElement.NameAsIdentifier() == "override")
|
if (overrideElement.NameAsIdentifier() == "override")
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!(e.ChangedData.BalanceChanged is Some<int> { Value: var changed })) { return; }
|
if (!(e.ChangedData.BalanceChanged is Some<int> { Value: var changed })) { return; }
|
||||||
|
|
||||||
if (changed != 0) { return; }
|
if (changed == 0) { return; }
|
||||||
|
|
||||||
bool isGain = changed > 0;
|
bool isGain = changed > 0;
|
||||||
Color clr = isGain ? GUIStyle.Yellow : GUIStyle.Red;
|
Color clr = isGain ? GUIStyle.Yellow : GUIStyle.Red;
|
||||||
|
|||||||
@@ -177,12 +177,13 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int price = prefab.Price.GetBuyprice(GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation);
|
int price = prefab.Price.GetBuyPrice(GetUpgradeLevel(prefab, category), Campaign.Map?.CurrentLocation);
|
||||||
int currentLevel = GetUpgradeLevel(prefab, category);
|
int currentLevel = GetUpgradeLevel(prefab, category);
|
||||||
|
|
||||||
if (currentLevel + 1 > prefab.MaxLevel)
|
int maxLevel = prefab.GetMaxLevelForCurrentSub();
|
||||||
|
if (currentLevel + 1 > maxLevel)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Tried to purchase \"{prefab.Name}\" over the max level! ({currentLevel + 1} > {prefab.MaxLevel}). The transaction has been cancelled.");
|
DebugConsole.ThrowError($"Tried to purchase \"{prefab.Name}\" over the max level! ({currentLevel + 1} > {maxLevel}). The transaction has been cancelled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +473,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
int newLevel = BuyUpgrade(prefab, category, Submarine.MainSub, level);
|
int newLevel = BuyUpgrade(prefab, category, Submarine.MainSub, level);
|
||||||
DebugConsole.Log($" - {category.Identifier}.{prefab.Identifier} lvl. {level}, new: ({newLevel})");
|
DebugConsole.Log($" - {category.Identifier}.{prefab.Identifier} lvl. {level}, new: ({newLevel})");
|
||||||
SetUpgradeLevel(prefab, category, Math.Clamp(GetRealUpgradeLevel(prefab, category) + level, 0, prefab.MaxLevel));
|
SetUpgradeLevel(prefab, category, GetRealUpgradeLevel(prefab, category) + level);
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingUpgrades.Clear();
|
PendingUpgrades.Clear();
|
||||||
@@ -652,16 +653,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the progress that is shown on the store interface.
|
/// Gets the progress that is shown on the store interface.
|
||||||
/// Includes values stored in the metadata and <see cref="PendingUpgrades"/>
|
/// Includes values stored in the metadata and <see cref="PendingUpgrades"/>, and takes submarine tier and class restrictions into account
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prefab"></param>
|
|
||||||
/// <param name="category"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public int GetUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category)
|
public int GetUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category)
|
||||||
{
|
{
|
||||||
if (!Metadata.HasKey(FormatIdentifier(prefab, category))) { return GetPendingLevel(); }
|
if (!Metadata.HasKey(FormatIdentifier(prefab, category))) { return GetPendingLevel(); }
|
||||||
|
|
||||||
return GetRealUpgradeLevel(prefab, category) + GetPendingLevel();
|
return Math.Min(GetRealUpgradeLevel(prefab, category) + GetPendingLevel(), prefab.GetMaxLevelForCurrentSub());
|
||||||
|
|
||||||
int GetPendingLevel()
|
int GetPendingLevel()
|
||||||
{
|
{
|
||||||
@@ -671,11 +669,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the level of the upgrade that is stored in the metadata.
|
/// Gets the level of the upgrade that is stored in the metadata. May be higher than the apparent level on the current sub if the player has switched to a lower-tier sub
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prefab"></param>
|
|
||||||
/// <param name="category"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public int GetRealUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category)
|
public int GetRealUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category)
|
||||||
{
|
{
|
||||||
return !Metadata.HasKey(FormatIdentifier(prefab, category)) ? 0 : Metadata.GetInt(FormatIdentifier(prefab, category), 0);
|
return !Metadata.HasKey(FormatIdentifier(prefab, category)) ? 0 : Metadata.GetInt(FormatIdentifier(prefab, category), 0);
|
||||||
@@ -684,9 +679,6 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stores the target upgrade level in the campaign metadata.
|
/// Stores the target upgrade level in the campaign metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prefab"></param>
|
|
||||||
/// <param name="category"></param>
|
|
||||||
/// <param name="level"></param>
|
|
||||||
private void SetUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category, int level)
|
private void SetUpgradeLevel(UpgradePrefab prefab, UpgradeCategory category, int level)
|
||||||
{
|
{
|
||||||
Metadata.SetValue(FormatIdentifier(prefab, category), level);
|
Metadata.SetValue(FormatIdentifier(prefab, category), level);
|
||||||
|
|||||||
@@ -1164,8 +1164,11 @@ namespace Barotrauma.Items.Components
|
|||||||
public override void ReceiveSignal(Signal signal, Connection connection)
|
public override void ReceiveSignal(Signal signal, Connection connection)
|
||||||
{
|
{
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient &&
|
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
|
||||||
!(GameMain.GameSession?.Campaign?.AllowedToManageCampaign(ClientPermissions.ManageMap) ?? false))
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GameMain.GameSession?.Campaign != null && !CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageMap))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MaxAttachDistance = 150.0f;
|
private const float MaxAttachDistance = ItemPrefab.DefaultInteractDistance * 0.95f;
|
||||||
|
|
||||||
//the position(s) in the item that the Character grabs
|
//the position(s) in the item that the Character grabs
|
||||||
protected Vector2[] handlePos;
|
protected Vector2[] handlePos;
|
||||||
@@ -731,10 +731,24 @@ namespace Barotrauma.Items.Components
|
|||||||
mouseDiff = mouseDiff.ClampLength(MaxAttachDistance);
|
mouseDiff = mouseDiff.ClampLength(MaxAttachDistance);
|
||||||
|
|
||||||
Vector2 userPos = useWorldCoordinates ? user.WorldPosition : user.Position;
|
Vector2 userPos = useWorldCoordinates ? user.WorldPosition : user.Position;
|
||||||
|
|
||||||
Vector2 attachPos = userPos + mouseDiff;
|
Vector2 attachPos = userPos + mouseDiff;
|
||||||
|
|
||||||
if (user.Submarine == null && Level.Loaded != null)
|
if (user.Submarine != null)
|
||||||
|
{
|
||||||
|
if (Submarine.PickBody(
|
||||||
|
ConvertUnits.ToSimUnits(user.Position),
|
||||||
|
ConvertUnits.ToSimUnits(user.Position + mouseDiff), collisionCategory: Physics.CollisionWall) != null)
|
||||||
|
{
|
||||||
|
attachPos = userPos + mouseDiff * Submarine.LastPickedFraction;
|
||||||
|
|
||||||
|
//round down if we're placing on the right side and vice versa: ensures we don't round the position inside a wall
|
||||||
|
return
|
||||||
|
new Vector2(
|
||||||
|
mouseDiff.X > 0 ? (float)Math.Floor(attachPos.X / Submarine.GridSize.X) * Submarine.GridSize.X : (float)Math.Ceiling(attachPos.X / Submarine.GridSize.X) * Submarine.GridSize.X,
|
||||||
|
mouseDiff.Y > 0 ? (float)Math.Floor(attachPos.Y / Submarine.GridSize.Y) * Submarine.GridSize.X : (float)Math.Ceiling(attachPos.Y / Submarine.GridSize.Y) * Submarine.GridSize.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Level.Loaded != null)
|
||||||
{
|
{
|
||||||
bool edgeFound = false;
|
bool edgeFound = false;
|
||||||
foreach (var cell in Level.Loaded.GetCells(attachPos))
|
foreach (var cell in Level.Loaded.GetCells(attachPos))
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace Barotrauma.Items.Components
|
|||||||
reloadTimer = reload;
|
reloadTimer = reload;
|
||||||
reloadTimer /= 1f + character.GetStatValue(StatTypes.MeleeAttackSpeed);
|
reloadTimer /= 1f + character.GetStatValue(StatTypes.MeleeAttackSpeed);
|
||||||
reloadTimer /= 1f + item.GetQualityModifier(Quality.StatType.StrikingSpeedMultiplier);
|
reloadTimer /= 1f + item.GetQualityModifier(Quality.StatType.StrikingSpeedMultiplier);
|
||||||
character.AnimController.LockFlippingUntil = (float)Timing.TotalTime + reloadTimer;
|
character.AnimController.LockFlippingUntil = (float)Timing.TotalTime + reloadTimer * 0.9f;
|
||||||
|
|
||||||
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
|
item.body.FarseerBody.CollisionCategories = Physics.CollisionProjectile;
|
||||||
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionItemBlocking;
|
item.body.FarseerBody.CollidesWith = Physics.CollisionCharacter | Physics.CollisionWall | Physics.CollisionItemBlocking;
|
||||||
|
|||||||
@@ -514,7 +514,7 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
|
||||||
{
|
{
|
||||||
if (Rand.Range(0.0f, 1.0f) < FireProbability * deltaTime)
|
if (Rand.Range(0.0f, 1.0f) < FireProbability * deltaTime && item.CurrentHull != null)
|
||||||
{
|
{
|
||||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * lastPickedFraction * 0.9f);
|
Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * lastPickedFraction * 0.9f);
|
||||||
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
|
if (item.CurrentHull.Submarine != null) { displayPos += item.CurrentHull.Submarine.Position; }
|
||||||
|
|||||||
@@ -284,9 +284,10 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) =>
|
Entity.Spawner.AddItemToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) =>
|
||||||
{
|
{
|
||||||
spawnedItem.SpawnedInCurrentOutpost = item.SpawnedInCurrentOutpost;
|
|
||||||
spawnedItem.StolenDuringRound = targetItem.StolenDuringRound;
|
spawnedItem.StolenDuringRound = targetItem.StolenDuringRound;
|
||||||
spawnedItem.AllowStealing = targetItem.AllowStealing;
|
spawnedItem.AllowStealing = targetItem.AllowStealing;
|
||||||
|
spawnedItem.OriginalOutpost = targetItem.OriginalOutpost;
|
||||||
|
spawnedItem.SpawnedInCurrentOutpost = targetItem.SpawnedInCurrentOutpost;
|
||||||
for (int i = 0; i < outputContainer.Capacity; i++)
|
for (int i = 0; i < outputContainer.Capacity; i++)
|
||||||
{
|
{
|
||||||
var containedItem = outputContainer.Inventory.GetItemAt(i);
|
var containedItem = outputContainer.Inventory.GetItemAt(i);
|
||||||
|
|||||||
@@ -83,8 +83,16 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (lastUser == value) { return; }
|
if (lastUser == value) { return; }
|
||||||
lastUser = value;
|
lastUser = value;
|
||||||
degreeOfSuccess = lastUser == null ? 0.0f : Math.Min(DegreeOfSuccess(lastUser), 1.0f);
|
if (lastUser == null)
|
||||||
LastUserWasPlayer = lastUser.IsPlayer;
|
{
|
||||||
|
degreeOfSuccess = 0.0f;
|
||||||
|
LastUserWasPlayer = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
degreeOfSuccess = Math.Min(DegreeOfSuccess(lastUser), 1.0f);
|
||||||
|
LastUserWasPlayer = lastUser.IsPlayer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -390,6 +390,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public static readonly PrefabCollection<ItemPrefab> Prefabs = new PrefabCollection<ItemPrefab>();
|
public static readonly PrefabCollection<ItemPrefab> Prefabs = new PrefabCollection<ItemPrefab>();
|
||||||
|
|
||||||
|
public const float DefaultInteractDistance = 120.0f;
|
||||||
|
|
||||||
//default size
|
//default size
|
||||||
public Vector2 Size { get; private set; }
|
public Vector2 Size { get; private set; }
|
||||||
|
|
||||||
@@ -590,7 +592,7 @@ namespace Barotrauma
|
|||||||
public override ImmutableHashSet<string> Aliases => aliases;
|
public override ImmutableHashSet<string> Aliases => aliases;
|
||||||
|
|
||||||
//how close the Character has to be to the item to pick it up
|
//how close the Character has to be to the item to pick it up
|
||||||
[Serialize(120.0f, IsPropertySaveable.No)]
|
[Serialize(DefaultInteractDistance, IsPropertySaveable.No)]
|
||||||
public float InteractDistance { get; private set; }
|
public float InteractDistance { get; private set; }
|
||||||
|
|
||||||
// this can be used to allow items which are behind other items tp
|
// this can be used to allow items which are behind other items tp
|
||||||
|
|||||||
@@ -3015,6 +3015,7 @@ namespace Barotrauma
|
|||||||
var selectedLocation = allValidLocations.FirstOrDefault(l =>
|
var selectedLocation = allValidLocations.FirstOrDefault(l =>
|
||||||
Vector2.Distance(l.Edge.Point1, l.Edge.Point2) is float edgeLength &&
|
Vector2.Distance(l.Edge.Point1, l.Edge.Point2) is float edgeLength &&
|
||||||
!l.Edge.OutsideLevel &&
|
!l.Edge.OutsideLevel &&
|
||||||
|
((l.Edge.Cell1?.IsDestructible ?? false) || (l.Edge.Cell2?.IsDestructible ?? false)) &&
|
||||||
requiredAmount <= (int)Math.Floor(edgeLength / ((1.0f - maxResourceOverlap) * prefab.Size.X)));
|
requiredAmount <= (int)Math.Floor(edgeLength / ((1.0f - maxResourceOverlap) * prefab.Size.X)));
|
||||||
|
|
||||||
|
|
||||||
@@ -3905,7 +3906,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private bool HasEndOutpost()
|
private bool HasEndOutpost()
|
||||||
{
|
{
|
||||||
if (preSelectedStartOutpost != null) { return true; }
|
if (preSelectedEndOutpost != null) { return true; }
|
||||||
//don't create an end outpost for locations
|
//don't create an end outpost for locations
|
||||||
if (LevelData.Type == LevelData.LevelType.Outpost) { return false; }
|
if (LevelData.Type == LevelData.LevelType.Outpost) { return false; }
|
||||||
if (EndLocation != null && !EndLocation.Type.HasOutpost) { return false; }
|
if (EndLocation != null && !EndLocation.Type.HasOutpost) { return false; }
|
||||||
|
|||||||
@@ -906,11 +906,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public LocationType GetLocationType()
|
public LocationType GetLocationType()
|
||||||
{
|
{
|
||||||
if (IsCriticallyRadiated() && LocationType.Prefabs[Type.ReplaceInRadiation] is { } newLocationType)
|
if (IsCriticallyRadiated() && !Type.ReplaceInRadiation.IsEmpty)
|
||||||
{
|
{
|
||||||
return newLocationType;
|
if (LocationType.Prefabs.TryGet(Type.ReplaceInRadiation, out LocationType newLocationType))
|
||||||
|
{
|
||||||
|
return newLocationType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Error when trying to get a new location type for an irradiated location - location type \"{newLocationType}\" not found.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace Barotrauma
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReplaceInRadiation { get; }
|
public Identifier ReplaceInRadiation { get; }
|
||||||
|
|
||||||
public Sprite Sprite { get; private set; }
|
public Sprite Sprite { get; private set; }
|
||||||
public Sprite RadiationSprite { get; }
|
public Sprite RadiationSprite { get; }
|
||||||
@@ -108,7 +108,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
HideEntitySubcategories = element.GetAttributeStringArray("hideentitysubcategories", Array.Empty<string>()).ToList();
|
HideEntitySubcategories = element.GetAttributeStringArray("hideentitysubcategories", Array.Empty<string>()).ToList();
|
||||||
|
|
||||||
ReplaceInRadiation = element.GetAttributeString(nameof(ReplaceInRadiation).ToLower(), "");
|
ReplaceInRadiation = element.GetAttributeIdentifier(nameof(ReplaceInRadiation), Identifier.Empty);
|
||||||
|
|
||||||
string teamStr = element.GetAttributeString("outpostteam", "FriendlyNPC");
|
string teamStr = element.GetAttributeString("outpostteam", "FriendlyNPC");
|
||||||
Enum.TryParse(teamStr, out OutpostTeam);
|
Enum.TryParse(teamStr, out OutpostTeam);
|
||||||
|
|||||||
@@ -560,6 +560,42 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//make sure the location at the right side of the gate between biomes isn't a dead-end
|
||||||
|
//those may sometimes generate if all the connections of the right-side location lead to the previous biome
|
||||||
|
//(i.e. a situation where the adjacent locations happen to be at the left side of the border of the biomes, see see Regalis11/Barotrauma#10047)
|
||||||
|
for (int i = 0; i < Connections.Count; i++)
|
||||||
|
{
|
||||||
|
var connection = Connections[i];
|
||||||
|
if (!connection.Locked) { continue; }
|
||||||
|
var rightMostLocation =
|
||||||
|
connection.Locations[0].MapPosition.X > connection.Locations[1].MapPosition.X ?
|
||||||
|
connection.Locations[0] :
|
||||||
|
connection.Locations[1];
|
||||||
|
|
||||||
|
//if there's only one connection (= the connection between biomes), create a new connection to the closest location to the right
|
||||||
|
if (rightMostLocation.Connections.Count == 1)
|
||||||
|
{
|
||||||
|
Location closestLocation = null;
|
||||||
|
float closestDist = float.PositiveInfinity;
|
||||||
|
foreach (Location otherLocation in Locations)
|
||||||
|
{
|
||||||
|
if (otherLocation == rightMostLocation || otherLocation.MapPosition.X < rightMostLocation.MapPosition.X) { continue; }
|
||||||
|
float dist = Vector2.DistanceSquared(rightMostLocation.MapPosition, otherLocation.MapPosition);
|
||||||
|
if (dist < closestDist || closestLocation == null)
|
||||||
|
{
|
||||||
|
closestLocation = otherLocation;
|
||||||
|
closestDist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newConnection = new LocationConnection(rightMostLocation, closestLocation);
|
||||||
|
rightMostLocation.Connections.Add(newConnection);
|
||||||
|
closestLocation.Connections.Add(newConnection);
|
||||||
|
Connections.Add(newConnection);
|
||||||
|
GenerateLocationConnectionVisuals(newConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//remove orphans
|
//remove orphans
|
||||||
Locations.RemoveAll(l => !Connections.Any(c => c.Locations.Contains(l)));
|
Locations.RemoveAll(l => !Connections.Any(c => c.Locations.Contains(l)));
|
||||||
|
|
||||||
@@ -606,7 +642,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void GenerateLocationConnectionVisuals();
|
partial void GenerateAllLocationConnectionVisuals();
|
||||||
|
|
||||||
|
partial void GenerateLocationConnectionVisuals(LocationConnection connection);
|
||||||
|
|
||||||
private int GetZoneIndex(float xPos)
|
private int GetZoneIndex(float xPos)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,23 +8,7 @@ using Lidgren.Network;
|
|||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
interface IWritableBitField
|
sealed class WriteOnlyBitField : IDisposable
|
||||||
{
|
|
||||||
public void WriteBoolean(bool b);
|
|
||||||
public void WriteInteger(int value, int min, int max);
|
|
||||||
public void WriteFloat(float value, float min, float max, int numberOfBits);
|
|
||||||
|
|
||||||
public void WriteToMessage(IWriteMessage msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IReadableBitField
|
|
||||||
{
|
|
||||||
public bool ReadBoolean();
|
|
||||||
public int ReadInteger(int min, int max);
|
|
||||||
public float ReadFloat(float min, float max, int numberOfBits);
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class WriteOnlyBitField : IWritableBitField, IDisposable
|
|
||||||
{
|
{
|
||||||
private const int AmountOfBoolsInByte = 7; // Reserve last bit for end marker
|
private const int AmountOfBoolsInByte = 7; // Reserve last bit for end marker
|
||||||
private readonly List<byte> Buffer = new List<byte>();
|
private readonly List<byte> Buffer = new List<byte>();
|
||||||
@@ -100,7 +84,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ReadOnlyBitField : IReadableBitField
|
sealed class ReadOnlyBitField
|
||||||
{
|
{
|
||||||
private const int AmountOfBoolsInByte = 7; // Reserve last bit for end marker
|
private const int AmountOfBoolsInByte = 7; // Reserve last bit for end marker
|
||||||
private readonly ImmutableArray<byte> buffer;
|
private readonly ImmutableArray<byte> buffer;
|
||||||
@@ -110,17 +94,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
List<byte> bytes = new List<byte>();
|
List<byte> bytes = new List<byte>();
|
||||||
byte currentByte;
|
byte currentByte;
|
||||||
int reads = 0;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
if (inc.BitPosition >= inc.LengthBits)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to find the end of the bit field: end of the message reached.");
|
||||||
|
}
|
||||||
currentByte = inc.ReadByte();
|
currentByte = inc.ReadByte();
|
||||||
bytes.Add(currentByte);
|
bytes.Add(currentByte);
|
||||||
|
|
||||||
reads++;
|
|
||||||
if (reads > 100)
|
|
||||||
{
|
|
||||||
throw new Exception($"Failed to find the end of the bit field after 100 reads. Terminating to prevent the game from freezing.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (!IsBitSet(currentByte, AmountOfBoolsInByte));
|
while (!IsBitSet(currentByte, AmountOfBoolsInByte));
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ namespace Barotrauma.Networking
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (AggregateException aggregateException)
|
||||||
|
{
|
||||||
|
if (aggregateException.InnerException is OperationCanceledException) { return -1; }
|
||||||
|
throw;
|
||||||
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
public interface IReadWriteBehavior
|
public interface IReadWriteBehavior
|
||||||
{
|
{
|
||||||
public delegate object? ReadDelegate(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField);
|
public delegate object? ReadDelegate(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField);
|
||||||
|
|
||||||
public delegate void WriteDelegate(object? obj, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField);
|
public delegate void WriteDelegate(object? obj, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField);
|
||||||
|
|
||||||
public ReadDelegate ReadAction { get; }
|
public ReadDelegate ReadAction { get; }
|
||||||
public WriteDelegate WriteAction { get; }
|
public WriteDelegate WriteAction { get; }
|
||||||
@@ -71,9 +71,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public readonly struct ReadWriteBehavior<T> : IReadWriteBehavior
|
public readonly struct ReadWriteBehavior<T> : IReadWriteBehavior
|
||||||
{
|
{
|
||||||
public delegate T ReadDelegate(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField);
|
public delegate T ReadDelegate(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField);
|
||||||
|
|
||||||
public delegate void WriteDelegate(T obj, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField);
|
public delegate void WriteDelegate(T obj, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField);
|
||||||
|
|
||||||
public IReadWriteBehavior.ReadDelegate ReadAction { get; }
|
public IReadWriteBehavior.ReadDelegate ReadAction { get; }
|
||||||
public IReadWriteBehavior.WriteDelegate WriteAction { get; }
|
public IReadWriteBehavior.WriteDelegate WriteAction { get; }
|
||||||
@@ -256,18 +256,18 @@ namespace Barotrauma
|
|||||||
ReadImmutableArray<object>,
|
ReadImmutableArray<object>,
|
||||||
WriteImmutableArray<object>);
|
WriteImmutableArray<object>);
|
||||||
|
|
||||||
private static ImmutableArray<T> ReadImmutableArray<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : notnull
|
private static ImmutableArray<T> ReadImmutableArray<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
return ReadArray<T>(inc, attribute, bitField).ToImmutableArray();
|
return ReadArray<T>(inc, attribute, bitField).ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteImmutableArray<T>(ImmutableArray<T> array, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
private static void WriteImmutableArray<T>(ImmutableArray<T> array, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(array);
|
ToolBox.ThrowIfNull(array);
|
||||||
WriteIReadOnlyCollection<T>(array, attribute, msg, bitField);
|
WriteIReadOnlyCollection<T>(array, attribute, msg, bitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T[] ReadArray<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : notnull
|
private static T[] ReadArray<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
int length = bitField.ReadInteger(0, attribute.ArrayMaxSize);
|
int length = bitField.ReadInteger(0, attribute.ArrayMaxSize);
|
||||||
|
|
||||||
@@ -286,13 +286,13 @@ namespace Barotrauma
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteArray<T>(T[] array, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
private static void WriteArray<T>(T[] array, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(array);
|
ToolBox.ThrowIfNull(array);
|
||||||
WriteIReadOnlyCollection(array, attribute, msg, bitField);
|
WriteIReadOnlyCollection(array, attribute, msg, bitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteIReadOnlyCollection<T>(IReadOnlyCollection<T> array, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
private static void WriteIReadOnlyCollection<T>(IReadOnlyCollection<T> array, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
bitField.WriteInteger(array.Count, 0, attribute.ArrayMaxSize);
|
bitField.WriteInteger(array.Count, 0, attribute.ArrayMaxSize);
|
||||||
|
|
||||||
@@ -307,18 +307,18 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T ReadINetSerializableStruct<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : INetSerializableStruct
|
private static T ReadINetSerializableStruct<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : INetSerializableStruct
|
||||||
{
|
{
|
||||||
return INetSerializableStruct.ReadInternal<T>(inc, bitField);
|
return INetSerializableStruct.ReadInternal<T>(inc, bitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteINetSerializableStruct<T>(T serializableStruct, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : INetSerializableStruct
|
private static void WriteINetSerializableStruct<T>(T serializableStruct, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : INetSerializableStruct
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(serializableStruct);
|
ToolBox.ThrowIfNull(serializableStruct);
|
||||||
serializableStruct.WriteInternal(msg, bitField);
|
serializableStruct.WriteInternal(msg, bitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T ReadEnum<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : Enum
|
private static T ReadEnum<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : Enum
|
||||||
{
|
{
|
||||||
var type = typeof(T);
|
var type = typeof(T);
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ namespace Barotrauma
|
|||||||
throw new InvalidOperationException($"An enum {type} with value {enumIndex} could not be found in {nameof(ReadEnum)}");
|
throw new InvalidOperationException($"An enum {type} with value {enumIndex} could not be found in {nameof(ReadEnum)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteEnum<T>(T value, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : Enum
|
private static void WriteEnum<T>(T value, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : Enum
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(value);
|
ToolBox.ThrowIfNull(value);
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ namespace Barotrauma
|
|||||||
bitField.WriteInteger((int)Convert.ChangeType(value, value.GetTypeCode()), range.Start, range.End);
|
bitField.WriteInteger((int)Convert.ChangeType(value, value.GetTypeCode()), range.Start, range.End);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T? ReadNullable<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : struct =>
|
private static T? ReadNullable<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : struct =>
|
||||||
ReadOption<T>(inc, attribute, bitField) switch
|
ReadOption<T>(inc, attribute, bitField) switch
|
||||||
{
|
{
|
||||||
Some<T> { Value: var value } => value,
|
Some<T> { Value: var value } => value,
|
||||||
@@ -354,10 +354,10 @@ namespace Barotrauma
|
|||||||
_ => throw new ArgumentOutOfRangeException()
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
};
|
};
|
||||||
|
|
||||||
private static void WriteNullable<T>(T? value, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : struct =>
|
private static void WriteNullable<T>(T? value, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : struct =>
|
||||||
WriteOption<T>(value.HasValue ? Option<T>.Some(value.Value) : Option<T>.None(), attribute, msg, bitField);
|
WriteOption<T>(value.HasValue ? Option<T>.Some(value.Value) : Option<T>.None(), attribute, msg, bitField);
|
||||||
|
|
||||||
private static Option<T> ReadOption<T>(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) where T : notnull
|
private static Option<T> ReadOption<T>(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
bool hasValue = bitField.ReadBoolean();
|
bool hasValue = bitField.ReadBoolean();
|
||||||
if (!hasValue)
|
if (!hasValue)
|
||||||
@@ -373,7 +373,7 @@ namespace Barotrauma
|
|||||||
throw new InvalidOperationException($"Could not find suitable behavior for type {typeof(T)} in {nameof(ReadOption)}");
|
throw new InvalidOperationException($"Could not find suitable behavior for type {typeof(T)} in {nameof(ReadOption)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteOption<T>(Option<T> option, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) where T : notnull
|
private static void WriteOption<T>(Option<T> option, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) where T : notnull
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(option);
|
ToolBox.ThrowIfNull(option);
|
||||||
|
|
||||||
@@ -391,22 +391,22 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ReadBoolean(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => bitField.ReadBoolean();
|
private static bool ReadBoolean(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => bitField.ReadBoolean();
|
||||||
private static void WriteBoolean(bool b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { bitField.WriteBoolean(b); }
|
private static void WriteBoolean(bool b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { bitField.WriteBoolean(b); }
|
||||||
|
|
||||||
private static byte ReadByte(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadByte();
|
private static byte ReadByte(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadByte();
|
||||||
private static void WriteByte(byte b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteByte(b); }
|
private static void WriteByte(byte b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteByte(b); }
|
||||||
|
|
||||||
private static ushort ReadUInt16(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt16();
|
private static ushort ReadUInt16(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadUInt16();
|
||||||
private static void WriteUInt16(ushort b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt16(b); }
|
private static void WriteUInt16(ushort b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteUInt16(b); }
|
||||||
|
|
||||||
private static short ReadInt16(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadInt16();
|
private static short ReadInt16(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadInt16();
|
||||||
private static void WriteInt16(short b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteInt16(b); }
|
private static void WriteInt16(short b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteInt16(b); }
|
||||||
|
|
||||||
private static uint ReadUInt32(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt32();
|
private static uint ReadUInt32(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadUInt32();
|
||||||
private static void WriteUInt32(uint b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt32(b); }
|
private static void WriteUInt32(uint b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteUInt32(b); }
|
||||||
|
|
||||||
private static int ReadInt32(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
private static int ReadInt32(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
if (IsRanged(attribute.MinValueInt, attribute.MaxValueInt))
|
if (IsRanged(attribute.MinValueInt, attribute.MaxValueInt))
|
||||||
{
|
{
|
||||||
@@ -416,7 +416,7 @@ namespace Barotrauma
|
|||||||
return inc.ReadInt32();
|
return inc.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteInt32(int i, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
private static void WriteInt32(int i, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(i);
|
ToolBox.ThrowIfNull(i);
|
||||||
|
|
||||||
@@ -429,13 +429,13 @@ namespace Barotrauma
|
|||||||
msg.WriteInt32(i);
|
msg.WriteInt32(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ulong ReadUInt64(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt64();
|
private static ulong ReadUInt64(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadUInt64();
|
||||||
private static void WriteUInt64(ulong b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt64(b); }
|
private static void WriteUInt64(ulong b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteUInt64(b); }
|
||||||
|
|
||||||
private static long ReadInt64(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadInt64();
|
private static long ReadInt64(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadInt64();
|
||||||
private static void WriteInt64(long b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteInt64(b); }
|
private static void WriteInt64(long b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteInt64(b); }
|
||||||
|
|
||||||
private static float ReadSingle(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
private static float ReadSingle(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
if (IsRanged(attribute.MinValueFloat, attribute.MaxValueFloat))
|
if (IsRanged(attribute.MinValueFloat, attribute.MaxValueFloat))
|
||||||
{
|
{
|
||||||
@@ -445,7 +445,7 @@ namespace Barotrauma
|
|||||||
return inc.ReadSingle();
|
return inc.ReadSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteSingle(float f, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
private static void WriteSingle(float f, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(f);
|
ToolBox.ThrowIfNull(f);
|
||||||
|
|
||||||
@@ -458,16 +458,16 @@ namespace Barotrauma
|
|||||||
msg.WriteSingle(f);
|
msg.WriteSingle(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double ReadDouble(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadDouble();
|
private static double ReadDouble(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadDouble();
|
||||||
private static void WriteDouble(double b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteDouble(b); }
|
private static void WriteDouble(double b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteDouble(b); }
|
||||||
|
|
||||||
private static string ReadString(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadString();
|
private static string ReadString(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadString();
|
||||||
private static void WriteString(string b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteString(b); }
|
private static void WriteString(string b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteString(b); }
|
||||||
|
|
||||||
private static Identifier ReadIdentifier(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadIdentifier();
|
private static Identifier ReadIdentifier(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => inc.ReadIdentifier();
|
||||||
private static void WriteIdentifier(Identifier b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteIdentifier(b); }
|
private static void WriteIdentifier(Identifier b, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField) { msg.WriteIdentifier(b); }
|
||||||
|
|
||||||
private static AccountId ReadAccountId(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
private static AccountId ReadAccountId(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
string str = inc.ReadString();
|
string str = inc.ReadString();
|
||||||
return AccountId.Parse(str).TryUnwrap(out var accountId)
|
return AccountId.Parse(str).TryUnwrap(out var accountId)
|
||||||
@@ -475,14 +475,14 @@ namespace Barotrauma
|
|||||||
: throw new InvalidCastException($"Could not parse \"{str}\" as an {nameof(AccountId)}");
|
: throw new InvalidCastException($"Could not parse \"{str}\" as an {nameof(AccountId)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteAccountId(AccountId accountId, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
private static void WriteAccountId(AccountId accountId, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
msg.WriteString(accountId.StringRepresentation);
|
msg.WriteString(accountId.StringRepresentation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Color ReadColor(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => attribute.IncludeColorAlpha ? inc.ReadColorR8G8B8A8() : inc.ReadColorR8G8B8();
|
private static Color ReadColor(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField) => attribute.IncludeColorAlpha ? inc.ReadColorR8G8B8A8() : inc.ReadColorR8G8B8();
|
||||||
|
|
||||||
private static void WriteColor(Color color, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
private static void WriteColor(Color color, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(color);
|
ToolBox.ThrowIfNull(color);
|
||||||
|
|
||||||
@@ -495,7 +495,7 @@ namespace Barotrauma
|
|||||||
msg.WriteColorR8G8B8(color);
|
msg.WriteColorR8G8B8(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector2 ReadVector2(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
|
private static Vector2 ReadVector2(IReadMessage inc, NetworkSerialize attribute, ReadOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
float x = ReadSingle(inc, attribute, bitField);
|
float x = ReadSingle(inc, attribute, bitField);
|
||||||
float y = ReadSingle(inc, attribute, bitField);
|
float y = ReadSingle(inc, attribute, bitField);
|
||||||
@@ -503,7 +503,7 @@ namespace Barotrauma
|
|||||||
return new Vector2(x, y);
|
return new Vector2(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteVector2(Vector2 vector2, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
|
private static void WriteVector2(Vector2 vector2, NetworkSerialize attribute, IWriteMessage msg, WriteOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
ToolBox.ThrowIfNull(vector2);
|
ToolBox.ThrowIfNull(vector2);
|
||||||
|
|
||||||
@@ -690,11 +690,11 @@ namespace Barotrauma
|
|||||||
/// <returns>A new struct of type T with fields and properties deserialized</returns>
|
/// <returns>A new struct of type T with fields and properties deserialized</returns>
|
||||||
public static T Read<T>(IReadMessage inc) where T : INetSerializableStruct
|
public static T Read<T>(IReadMessage inc) where T : INetSerializableStruct
|
||||||
{
|
{
|
||||||
IReadableBitField bitField = new ReadOnlyBitField(inc);
|
ReadOnlyBitField bitField = new ReadOnlyBitField(inc);
|
||||||
return ReadInternal<T>(inc, bitField);
|
return ReadInternal<T>(inc, bitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T ReadInternal<T>(IReadMessage inc, IReadableBitField bitField) where T : INetSerializableStruct
|
public static T ReadInternal<T>(IReadMessage inc, ReadOnlyBitField bitField) where T : INetSerializableStruct
|
||||||
{
|
{
|
||||||
object? newObject = Activator.CreateInstance(typeof(T));
|
object? newObject = Activator.CreateInstance(typeof(T));
|
||||||
if (newObject is null) { return default!; }
|
if (newObject is null) { return default!; }
|
||||||
@@ -744,14 +744,14 @@ namespace Barotrauma
|
|||||||
/// <param name="msg">Outgoing network message</param>
|
/// <param name="msg">Outgoing network message</param>
|
||||||
public void Write(IWriteMessage msg)
|
public void Write(IWriteMessage msg)
|
||||||
{
|
{
|
||||||
IWritableBitField bitField = new WriteOnlyBitField();
|
WriteOnlyBitField bitField = new WriteOnlyBitField();
|
||||||
IWriteMessage structWriteMsg = new WriteOnlyMessage();
|
IWriteMessage structWriteMsg = new WriteOnlyMessage();
|
||||||
WriteInternal(structWriteMsg, bitField);
|
WriteInternal(structWriteMsg, bitField);
|
||||||
bitField.WriteToMessage(msg);
|
bitField.WriteToMessage(msg);
|
||||||
msg.WriteBytes(structWriteMsg.Buffer, 0, structWriteMsg.LengthBytes);
|
msg.WriteBytes(structWriteMsg.Buffer, 0, structWriteMsg.LengthBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInternal(IWriteMessage msg, IWritableBitField bitField)
|
public void WriteInternal(IWriteMessage msg, WriteOnlyBitField bitField)
|
||||||
{
|
{
|
||||||
var properties = NetSerializableProperties.GetPropertiesAndFields(GetType());
|
var properties = NetSerializableProperties.GetPropertiesAndFields(GetType());
|
||||||
|
|
||||||
|
|||||||
+19
@@ -40,6 +40,25 @@ namespace Barotrauma.Networking
|
|||||||
return Option<LidgrenAddress>.None();
|
return Option<LidgrenAddress>.None();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Option<LidgrenAddress> ParseHostName(string endpointStr)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var resolvedAddresses = Dns.GetHostAddresses(endpointStr);
|
||||||
|
return resolvedAddresses.Any()
|
||||||
|
? Option<LidgrenAddress>.Some(new LidgrenAddress(resolvedAddresses.First()))
|
||||||
|
: Option<LidgrenAddress>.None();
|
||||||
|
}
|
||||||
|
catch (SocketException)
|
||||||
|
{
|
||||||
|
return Option<LidgrenAddress>.None();
|
||||||
|
}
|
||||||
|
catch (ArgumentOutOfRangeException)
|
||||||
|
{
|
||||||
|
return Option<LidgrenAddress>.None();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
=> obj switch
|
=> obj switch
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-1
@@ -23,6 +23,11 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
public new static Option<LidgrenEndpoint> Parse(string endpointStr)
|
public new static Option<LidgrenEndpoint> Parse(string endpointStr)
|
||||||
|
{
|
||||||
|
return ParseFromWithHostNameCheck(endpointStr, tryParseHostName: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Option<LidgrenEndpoint> ParseFromWithHostNameCheck(string endpointStr, bool tryParseHostName)
|
||||||
{
|
{
|
||||||
string hostName = endpointStr;
|
string hostName = endpointStr;
|
||||||
int port = NetConfig.DefaultPort;
|
int port = NetConfig.DefaultPort;
|
||||||
@@ -33,7 +38,8 @@ namespace Barotrauma.Networking
|
|||||||
port = int.TryParse(split[1], out var tmpPort) ? tmpPort : port;
|
port = int.TryParse(split[1], out var tmpPort) ? tmpPort : port;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LidgrenAddress.Parse(hostName).TryUnwrap(out var adr))
|
if (LidgrenAddress.Parse(hostName).TryUnwrap(out var adr) ||
|
||||||
|
(tryParseHostName && LidgrenAddress.ParseHostName(hostName).TryUnwrap(out adr)))
|
||||||
{
|
{
|
||||||
return Option<LidgrenEndpoint>.Some(new LidgrenEndpoint(adr.NetAddress, port));
|
return Option<LidgrenEndpoint>.Some(new LidgrenEndpoint(adr.NetAddress, port));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,12 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
internal static class MsgWriter
|
internal static class MsgWriter
|
||||||
{
|
{
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, bool val)
|
internal static void UpdateBitLength(ref int bitLength, int bitPos)
|
||||||
|
{
|
||||||
|
bitLength = Math.Max(bitLength, bitPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void WriteBoolean(ref byte[] buf, ref int bitPos, ref int bitLength, bool val)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
int resetPos = bitPos;
|
int resetPos = bitPos;
|
||||||
@@ -52,7 +57,7 @@ namespace Barotrauma.Networking
|
|||||||
buf[bytePos] &= bitMask;
|
buf[bytePos] &= bitMask;
|
||||||
if (val) buf[bytePos] |= bitFlag;
|
if (val) buf[bytePos] |= bitFlag;
|
||||||
bitPos++;
|
bitPos++;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
bool testVal = MsgReader.ReadBoolean(buf, ref resetPos);
|
bool testVal = MsgReader.ReadBoolean(buf, ref resetPos);
|
||||||
if (testVal != val || resetPos != bitPos)
|
if (testVal != val || resetPos != bitPos)
|
||||||
@@ -62,63 +67,71 @@ namespace Barotrauma.Networking
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WritePadBits(ref byte[] buf, ref int bitPos)
|
internal static void WritePadBits(ref byte[] buf, ref int bitPos, ref int bitLength)
|
||||||
{
|
{
|
||||||
int bitOffset = bitPos % 8;
|
int bitOffset = bitPos % 8;
|
||||||
bitPos += ((8 - bitOffset) % 8);
|
bitPos += ((8 - bitOffset) % 8);
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
EnsureBufferSize(ref buf, bitPos);
|
EnsureBufferSize(ref buf, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, byte val)
|
internal static void WriteByte(ref byte[] buf, ref int bitPos, ref int bitLength, byte val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 8);
|
EnsureBufferSize(ref buf, bitPos + 8);
|
||||||
NetBitWriter.WriteByte(val, 8, buf, bitPos);
|
NetBitWriter.WriteByte(val, 8, buf, bitPos);
|
||||||
bitPos += 8;
|
bitPos += 8;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, UInt16 val)
|
internal static void WriteUInt16(ref byte[] buf, ref int bitPos, ref int bitLength, UInt16 val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 16);
|
EnsureBufferSize(ref buf, bitPos + 16);
|
||||||
NetBitWriter.WriteUInt16(val, 16, buf, bitPos);
|
NetBitWriter.WriteUInt16(val, 16, buf, bitPos);
|
||||||
bitPos += 16;
|
bitPos += 16;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, Int16 val)
|
internal static void WriteInt16(ref byte[] buf, ref int bitPos, ref int bitLength, Int16 val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 16);
|
EnsureBufferSize(ref buf, bitPos + 16);
|
||||||
NetBitWriter.WriteUInt16((UInt16)val, 16, buf, bitPos);
|
NetBitWriter.WriteUInt16((UInt16)val, 16, buf, bitPos);
|
||||||
bitPos += 16;
|
bitPos += 16;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, UInt32 val)
|
internal static void WriteUInt32(ref byte[] buf, ref int bitPos, ref int bitLength, UInt32 val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 32);
|
EnsureBufferSize(ref buf, bitPos + 32);
|
||||||
NetBitWriter.WriteUInt32(val, 32, buf, bitPos);
|
NetBitWriter.WriteUInt32(val, 32, buf, bitPos);
|
||||||
bitPos += 32;
|
bitPos += 32;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, Int32 val)
|
internal static void WriteInt32(ref byte[] buf, ref int bitPos, ref int bitLength, Int32 val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 32);
|
EnsureBufferSize(ref buf, bitPos + 32);
|
||||||
NetBitWriter.WriteUInt32((UInt32)val, 32, buf, bitPos);
|
NetBitWriter.WriteUInt32((UInt32)val, 32, buf, bitPos);
|
||||||
bitPos += 32;
|
bitPos += 32;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, UInt64 val)
|
internal static void WriteUInt64(ref byte[] buf, ref int bitPos, ref int bitLength, UInt64 val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 64);
|
EnsureBufferSize(ref buf, bitPos + 64);
|
||||||
NetBitWriter.WriteUInt64(val, 64, buf, bitPos);
|
NetBitWriter.WriteUInt64(val, 64, buf, bitPos);
|
||||||
bitPos += 64;
|
bitPos += 64;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, Int64 val)
|
internal static void WriteInt64(ref byte[] buf, ref int bitPos, ref int bitLength, Int64 val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 64);
|
EnsureBufferSize(ref buf, bitPos + 64);
|
||||||
NetBitWriter.WriteUInt64((UInt64)val, 64, buf, bitPos);
|
NetBitWriter.WriteUInt64((UInt64)val, 64, buf, bitPos);
|
||||||
bitPos += 64;
|
bitPos += 64;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, Single val)
|
internal static void WriteSingle(ref byte[] buf, ref int bitPos, ref int bitLength, Single val)
|
||||||
{
|
{
|
||||||
// Use union to avoid BitConverter.GetBytes() which allocates memory on the heap
|
// Use union to avoid BitConverter.GetBytes() which allocates memory on the heap
|
||||||
SingleUIntUnion su;
|
SingleUIntUnion su;
|
||||||
@@ -129,61 +142,62 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
NetBitWriter.WriteUInt32(su.UIntValue, 32, buf, bitPos);
|
NetBitWriter.WriteUInt32(su.UIntValue, 32, buf, bitPos);
|
||||||
bitPos += 32;
|
bitPos += 32;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, Double val)
|
internal static void WriteDouble(ref byte[] buf, ref int bitPos, ref int bitLength, Double val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 64);
|
EnsureBufferSize(ref buf, bitPos + 64);
|
||||||
|
|
||||||
byte[] bytes = BitConverter.GetBytes(val);
|
byte[] bytes = BitConverter.GetBytes(val);
|
||||||
WriteBytes(ref buf, ref bitPos, bytes, 0, 8);
|
WriteBytes(ref buf, ref bitPos, ref bitLength, bytes, 0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, Color val)
|
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, ref int bitLength, Color val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 24);
|
EnsureBufferSize(ref buf, bitPos + 24);
|
||||||
|
|
||||||
Write(ref buf, ref bitPos, val.R);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.R);
|
||||||
Write(ref buf, ref bitPos, val.G);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.G);
|
||||||
Write(ref buf, ref bitPos, val.B);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.B);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, Color val)
|
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, ref int bitLength, Color val)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + 32);
|
EnsureBufferSize(ref buf, bitPos + 32);
|
||||||
|
|
||||||
Write(ref buf, ref bitPos, val.R);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.R);
|
||||||
Write(ref buf, ref bitPos, val.G);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.G);
|
||||||
Write(ref buf, ref bitPos, val.B);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.B);
|
||||||
Write(ref buf, ref bitPos, val.A);
|
WriteByte(ref buf, ref bitPos, ref bitLength, val.A);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Write(ref byte[] buf, ref int bitPos, string val)
|
internal static void WriteString(ref byte[] buf, ref int bitPos, ref int bitLength, string val)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(val))
|
if (string.IsNullOrEmpty(val))
|
||||||
{
|
{
|
||||||
WriteVariableUInt32(ref buf, ref bitPos, 0u);
|
WriteVariableUInt32(ref buf, ref bitPos, ref bitLength, 0u);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] bytes = Encoding.UTF8.GetBytes(val);
|
byte[] bytes = Encoding.UTF8.GetBytes(val);
|
||||||
WriteVariableUInt32(ref buf, ref bitPos, (uint)bytes.Length);
|
WriteVariableUInt32(ref buf, ref bitPos, ref bitLength, (uint)bytes.Length);
|
||||||
WriteBytes(ref buf, ref bitPos, bytes, 0, bytes.Length);
|
WriteBytes(ref buf, ref bitPos, ref bitLength, bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteVariableUInt32(ref byte[] buf, ref int bitPos, uint value)
|
internal static void WriteVariableUInt32(ref byte[] buf, ref int bitPos, ref int bitLength, uint value)
|
||||||
{
|
{
|
||||||
uint remainingValue = value;
|
uint remainingValue = value;
|
||||||
while (remainingValue >= 0x80)
|
while (remainingValue >= 0x80)
|
||||||
{
|
{
|
||||||
Write(ref buf, ref bitPos, (byte)(remainingValue | 0x80));
|
WriteByte(ref buf, ref bitPos, ref bitLength, (byte)(remainingValue | 0x80));
|
||||||
remainingValue >>= 7;
|
remainingValue >>= 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
Write(ref buf, ref bitPos, (byte)remainingValue);
|
WriteByte(ref buf, ref bitPos, ref bitLength, (byte)remainingValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, int val, int min, int max)
|
internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, ref int bitLength, int val, int min, int max)
|
||||||
{
|
{
|
||||||
uint range = (uint)(max - min);
|
uint range = (uint)(max - min);
|
||||||
int numberOfBits = NetUtility.BitsToHoldUInt(range);
|
int numberOfBits = NetUtility.BitsToHoldUInt(range);
|
||||||
@@ -193,9 +207,10 @@ namespace Barotrauma.Networking
|
|||||||
uint rvalue = (uint)(val - min);
|
uint rvalue = (uint)(val - min);
|
||||||
NetBitWriter.WriteUInt32(rvalue, numberOfBits, buf, bitPos);
|
NetBitWriter.WriteUInt32(rvalue, numberOfBits, buf, bitPos);
|
||||||
bitPos += numberOfBits;
|
bitPos += numberOfBits;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteRangedSingle(ref byte[] buf, ref int bitPos, Single val, Single min, Single max, int numberOfBits)
|
internal static void WriteRangedSingle(ref byte[] buf, ref int bitPos, ref int bitLength, Single val, Single min, Single max, int numberOfBits)
|
||||||
{
|
{
|
||||||
float range = max - min;
|
float range = max - min;
|
||||||
float unit = ((val - min) / range);
|
float unit = ((val - min) / range);
|
||||||
@@ -205,13 +220,15 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
NetBitWriter.WriteUInt32((UInt32)(maxVal * unit), numberOfBits, buf, bitPos);
|
NetBitWriter.WriteUInt32((UInt32)(maxVal * unit), numberOfBits, buf, bitPos);
|
||||||
bitPos += numberOfBits;
|
bitPos += numberOfBits;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void WriteBytes(ref byte[] buf, ref int bitPos, byte[] val, int pos, int length)
|
internal static void WriteBytes(ref byte[] buf, ref int bitPos, ref int bitLength, byte[] val, int pos, int length)
|
||||||
{
|
{
|
||||||
EnsureBufferSize(ref buf, bitPos + length * 8);
|
EnsureBufferSize(ref buf, bitPos + length * 8);
|
||||||
NetBitWriter.WriteBytes(val, pos, length, buf, bitPos);
|
NetBitWriter.WriteBytes(val, pos, length, buf, bitPos);
|
||||||
bitPos += length * 8;
|
bitPos += length * 8;
|
||||||
|
UpdateBitLength(ref bitLength, bitPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void EnsureBufferSize(ref byte[] buf, int numberOfBits)
|
internal static void EnsureBufferSize(ref byte[] buf, int numberOfBits)
|
||||||
@@ -447,77 +464,77 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void WriteBoolean(bool val)
|
public void WriteBoolean(bool val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteBoolean(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WritePadBits()
|
public void WritePadBits()
|
||||||
{
|
{
|
||||||
MsgWriter.WritePadBits(ref buf, ref seekPos);
|
MsgWriter.WritePadBits(ref buf, ref seekPos, ref lengthBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteByte(byte val)
|
public void WriteByte(byte val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteByte(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteUInt16(UInt16 val)
|
public void WriteUInt16(UInt16 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteUInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInt16(Int16 val)
|
public void WriteInt16(Int16 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteUInt32(UInt32 val)
|
public void WriteUInt32(UInt32 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInt32(Int32 val)
|
public void WriteInt32(Int32 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteUInt64(UInt64 val)
|
public void WriteUInt64(UInt64 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteUInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInt64(Int64 val)
|
public void WriteInt64(Int64 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteSingle(Single val)
|
public void WriteSingle(Single val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteSingle(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteDouble(Double val)
|
public void WriteDouble(Double val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteDouble(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteColorR8G8B8(Color val)
|
public void WriteColorR8G8B8(Color val)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, val);
|
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteColorR8G8B8A8(Color val)
|
public void WriteColorR8G8B8A8(Color val)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, val);
|
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteVariableUInt32(UInt32 val)
|
public void WriteVariableUInt32(UInt32 val)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, val);
|
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteString(String val)
|
public void WriteString(String val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteString(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteIdentifier(Identifier val)
|
public void WriteIdentifier(Identifier val)
|
||||||
@@ -527,17 +544,17 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void WriteRangedInteger(int val, int min, int max)
|
public void WriteRangedInteger(int val, int min, int max)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, val, min, max);
|
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, ref lengthBits, val, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
|
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, val, min, max, bitCount);
|
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, ref lengthBits, val, min, max, bitCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteBytes(byte[] val, int startPos, int length)
|
public void WriteBytes(byte[] val, int startPos, int length)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
|
MsgWriter.WriteBytes(ref buf, ref seekPos, ref lengthBits, val, startPos, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int length)
|
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int length)
|
||||||
@@ -814,77 +831,77 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void WriteBoolean(bool val)
|
public void WriteBoolean(bool val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteBoolean(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WritePadBits()
|
public void WritePadBits()
|
||||||
{
|
{
|
||||||
MsgWriter.WritePadBits(ref buf, ref seekPos);
|
MsgWriter.WritePadBits(ref buf, ref seekPos, ref lengthBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteByte(byte val)
|
public void WriteByte(byte val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteByte(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteUInt16(UInt16 val)
|
public void WriteUInt16(UInt16 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteUInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInt16(Int16 val)
|
public void WriteInt16(Int16 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteInt16(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteUInt32(UInt32 val)
|
public void WriteUInt32(UInt32 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInt32(Int32 val)
|
public void WriteInt32(Int32 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteUInt64(UInt64 val)
|
public void WriteUInt64(UInt64 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteUInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteInt64(Int64 val)
|
public void WriteInt64(Int64 val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteInt64(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteSingle(Single val)
|
public void WriteSingle(Single val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteSingle(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteDouble(Double val)
|
public void WriteDouble(Double val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteDouble(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteColorR8G8B8(Color val)
|
public void WriteColorR8G8B8(Color val)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, val);
|
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteColorR8G8B8A8(Color val)
|
public void WriteColorR8G8B8A8(Color val)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, val);
|
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteVariableUInt32(UInt32 val)
|
public void WriteVariableUInt32(UInt32 val)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, val);
|
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteString(String val)
|
public void WriteString(String val)
|
||||||
{
|
{
|
||||||
MsgWriter.Write(ref buf, ref seekPos, val);
|
MsgWriter.WriteString(ref buf, ref seekPos, ref lengthBits, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteIdentifier(Identifier val)
|
public void WriteIdentifier(Identifier val)
|
||||||
@@ -894,17 +911,17 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void WriteRangedInteger(int val, int min, int max)
|
public void WriteRangedInteger(int val, int min, int max)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, val, min, max);
|
MsgWriter.WriteRangedInteger(ref buf, ref seekPos, ref lengthBits, val, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
|
public void WriteRangedSingle(Single val, Single min, Single max, int bitCount)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, val, min, max, bitCount);
|
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, ref lengthBits, val, min, max, bitCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteBytes(byte[] val, int startPos, int length)
|
public void WriteBytes(byte[] val, int startPos, int length)
|
||||||
{
|
{
|
||||||
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
|
MsgWriter.WriteBytes(ref buf, ref seekPos, ref lengthBits, val, startPos, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReadBoolean()
|
public bool ReadBoolean()
|
||||||
|
|||||||
+7
-2
@@ -286,8 +286,13 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DateTime InstallTime => cachedDateTime ??= DateTime.UtcNow + TimeSpan.FromSeconds(InstallTimeDiffInSeconds);
|
public DateTime InstallTime => cachedDateTime ??= DateTime.UtcNow + TimeSpan.FromSeconds(InstallTimeDiffInSeconds);
|
||||||
public RegularPackage? RegularPackage => ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
public RegularPackage? RegularPackage =>
|
||||||
public CorePackage? CorePackage => ContentPackageManager.CorePackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Name.Equals(Name) && p.Hash.Equals(Hash)) ??
|
||||||
|
ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||||
|
|
||||||
|
public CorePackage? CorePackage =>
|
||||||
|
ContentPackageManager.CorePackages.FirstOrDefault(p => p.Name.Equals(Name) && p.Hash.Equals(Hash)) ??
|
||||||
|
ContentPackageManager.CorePackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||||
public ContentPackage? ContentPackage => (ContentPackage?)RegularPackage ?? CorePackage;
|
public ContentPackage? ContentPackage => (ContentPackage?)RegularPackage ?? CorePackage;
|
||||||
|
|
||||||
public ServerContentPackage() { }
|
public ServerContentPackage() { }
|
||||||
|
|||||||
@@ -1750,19 +1750,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
float spread = Rand.Range(-chosenItemSpawnInfo.AimSpreadRad, chosenItemSpawnInfo.AimSpreadRad);
|
float spread = Rand.Range(-chosenItemSpawnInfo.AimSpreadRad, chosenItemSpawnInfo.AimSpreadRad);
|
||||||
float rotation = chosenItemSpawnInfo.RotationRad;
|
float rotation = chosenItemSpawnInfo.RotationRad;
|
||||||
Vector2 worldPos;
|
Vector2 spawnPos = sourceBody != null ? sourceBody.SimPosition : entity.SimPosition;
|
||||||
if (sourceBody != null)
|
|
||||||
{
|
|
||||||
worldPos = sourceBody.Position;
|
|
||||||
if (user?.Submarine != null)
|
|
||||||
{
|
|
||||||
worldPos += user.Submarine.Position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worldPos = entity.WorldPosition;
|
|
||||||
}
|
|
||||||
switch (chosenItemSpawnInfo.RotationType)
|
switch (chosenItemSpawnInfo.RotationType)
|
||||||
{
|
{
|
||||||
case ItemSpawnInfo.SpawnRotationType.Fixed:
|
case ItemSpawnInfo.SpawnRotationType.Fixed:
|
||||||
@@ -1776,7 +1764,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ItemSpawnInfo.SpawnRotationType.Target:
|
case ItemSpawnInfo.SpawnRotationType.Target:
|
||||||
rotation = MathUtils.VectorToAngle(entity.WorldPosition - worldPos);
|
rotation = MathUtils.VectorToAngle(entity.SimPosition - spawnPos);
|
||||||
break;
|
break;
|
||||||
case ItemSpawnInfo.SpawnRotationType.Limb:
|
case ItemSpawnInfo.SpawnRotationType.Limb:
|
||||||
if (sourceBody != null)
|
if (sourceBody != null)
|
||||||
@@ -1820,10 +1808,7 @@ namespace Barotrauma
|
|||||||
rotation += spread;
|
rotation += spread;
|
||||||
if (projectile != null)
|
if (projectile != null)
|
||||||
{
|
{
|
||||||
projectile.Shoot(user,
|
projectile.Shoot(user, spawnPos, spawnPos, rotation,
|
||||||
ConvertUnits.ToSimUnits(worldPos),
|
|
||||||
ConvertUnits.ToSimUnits(worldPos),
|
|
||||||
rotation,
|
|
||||||
ignoredBodies: user?.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: true);
|
ignoredBodies: user?.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: true);
|
||||||
}
|
}
|
||||||
else if (newItem.body != null)
|
else if (newItem.body != null)
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetBuyprice(int level, Location? location = null)
|
public int GetBuyPrice(int level, Location? location = null)
|
||||||
{
|
{
|
||||||
int maxLevel = Prefab.MaxLevel;
|
int maxLevel = Prefab.GetMaxLevelForCurrentSub();
|
||||||
|
|
||||||
if (level > maxLevel) { maxLevel = level; }
|
if (level > maxLevel) { maxLevel = level; }
|
||||||
|
|
||||||
@@ -292,16 +292,10 @@ namespace Barotrauma
|
|||||||
onRemoveOverrideFile: null
|
onRemoveOverrideFile: null
|
||||||
);
|
);
|
||||||
|
|
||||||
private readonly int maxLevel;
|
/// <summary>
|
||||||
|
/// Maximum upgrade level without taking submarine tier or class restrictions into account
|
||||||
public int MaxLevel
|
/// </summary>
|
||||||
{
|
public readonly int MaxLevel;
|
||||||
get
|
|
||||||
{
|
|
||||||
Submarine? sub = GameMain.GameSession?.Submarine ?? Submarine.MainSub;
|
|
||||||
return sub is { Info: var info } ? GetMaxLevel(info) : maxLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalizedString Name { get; }
|
public LocalizedString Name { get; }
|
||||||
|
|
||||||
@@ -343,7 +337,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Name = element.GetAttributeString("name", string.Empty)!;
|
Name = element.GetAttributeString("name", string.Empty)!;
|
||||||
Description = element.GetAttributeString("description", string.Empty)!;
|
Description = element.GetAttributeString("description", string.Empty)!;
|
||||||
maxLevel = element.GetAttributeInt("maxlevel", 1);
|
MaxLevel = element.GetAttributeInt("maxlevel", 1);
|
||||||
SuppressWarnings = element.GetAttributeBool("supresswarnings", false);
|
SuppressWarnings = element.GetAttributeBool("supresswarnings", false);
|
||||||
HideInMenus = element.GetAttributeBool("hideinmenus", false);
|
HideInMenus = element.GetAttributeBool("hideinmenus", false);
|
||||||
SourceElement = element;
|
SourceElement = element;
|
||||||
@@ -428,9 +422,21 @@ namespace Barotrauma
|
|||||||
.ToImmutableHashSet() ?? ImmutableHashSet<Identifier>.Empty;
|
.ToImmutableHashSet() ?? ImmutableHashSet<Identifier>.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the maximum upgrade level for the current sub, taking tier and class restrictions into account
|
||||||
|
/// </summary>
|
||||||
|
public int GetMaxLevelForCurrentSub()
|
||||||
|
{
|
||||||
|
Submarine? sub = GameMain.GameSession?.Submarine ?? Submarine.MainSub;
|
||||||
|
return sub is { Info: var info } ? GetMaxLevel(info) : MaxLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the maximum upgrade level for the specified sub, taking tier and class restrictions into account
|
||||||
|
/// </summary>
|
||||||
public int GetMaxLevel(SubmarineInfo info)
|
public int GetMaxLevel(SubmarineInfo info)
|
||||||
{
|
{
|
||||||
int level = maxLevel;
|
int level = MaxLevel;
|
||||||
|
|
||||||
foreach (UpgradeMaxLevelMod mod in MaxLevelsMods)
|
foreach (UpgradeMaxLevelMod mod in MaxLevelsMods)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,54 @@
|
|||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.19.14.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Fixed submarine upgrades getting clamped to the maximum of that upgrade between rounds, disregarding class/tier bonuses.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.19.13.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Fixed "failed to find the end of the bit field after 100 reads" error when trying to join a server that has a large number of mods enabled.
|
||||||
|
- Fixed "Tandem Fire" talent causing a crash due to the changes in the previous version.
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
v0.19.12.0
|
||||||
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Fixed submarine upgrades getting lost if you switch to a lower-tier sub that can't have as many levels of upgrades as the current sub, and then back again.
|
||||||
|
- Fixed some monster events not being as common/uncommon as intended. In more technical terms (which may be of interest to modders): the commonness defined as an attribute of an EventSet did nothing, making the event default to a commonness of 1. The commonnesses defined for specific level types worked correctly.
|
||||||
|
- Fixed clients getting stuck in a non-functional lobby if they happen to disconnect or get kicked back to the lobby at a specific point when loading a new round.
|
||||||
|
- Fixed large turret hardpoint origin being off, causing turrets installed on a large hardpoint to be misaligned.
|
||||||
|
- Attempt to fix crashing when disconnecting from the server you're hosting.
|
||||||
|
- Fixed Ctrl+Shift+S shortcut (quicksave) not working in the sub editor.
|
||||||
|
- Fixed toolbelts and storage containers in old subs going inside toolbelts.
|
||||||
|
- Fixed submarine tier resetting to default when reopening the sub editor's save dialog.
|
||||||
|
- Fixed sub editor not taking filename case into account when saving an existing sub: if you'd try to save the file with a different filename case, it'd ask about overwriting the existing sub, but save it as a new file even if you opt to overwrite.
|
||||||
|
- Fixes to Herja room names (use Engineering, Gunnery compartment, etc. labels), add camera to the front, with a periscope for the captain.
|
||||||
|
- Fixed non-purchaseable talent items not being available as extra cargo.
|
||||||
|
- Sorted extra cargo alphabetically + added a filter box.
|
||||||
|
- Fixed taking items that spawned inside another item (e.g. tanks in a diving mask) from NPCs spawned by an event not counting as stealing.
|
||||||
|
- Fixed characters falling off ladders when using aimable tools.
|
||||||
|
- Fixed money gain/lose popups no longer showing in the campaign.
|
||||||
|
- Fixed inability to manage the campaign if there's no-one with permissions alive. Previously we allowed anyone to manage the campaign if there's no-one with permissions present in the server, but that's not enough, because the players with permissions can't end the round if they're dead. Now if there's no-one with permissions alive, anyone is allowed to manage the campaign.
|
||||||
|
- If Select and Deselect have been bound to the same key, the deselect input is ignored when interacting with another item than the selected one. Prevents e.g. falling off ladders when trying to open a hatch when both Select and Deselect have been bound to E.
|
||||||
|
- Made it possible to enter a hostname (e.g. someserver.com) in the direct join prompt.
|
||||||
|
- Adjusted the size of the submarine list elements in the server lobby to reduce the amount of empty space on large resolutions.
|
||||||
|
- Fixed event texts for the "scan ruin" mission being in an incorrect language.
|
||||||
|
- Attachable items cannot be attached inside walls.
|
||||||
|
- Fixed distance at which you can attach items being slightly longer than the interact distance, making it possible to attach items out of reach.
|
||||||
|
- Fixed inability to turn when you're dual wielding melee weapons and attacking continuously.
|
||||||
|
- Fixed inability to cancel deconstruction if there's non-deconstructible items in the queue.
|
||||||
|
- Fixed local copy of a mod you're publishing not using the version number you've entered in the publish menu.
|
||||||
|
- Fixed crashing when trying to open the tab menu's character tab with a character who has no personality trait (may happen e.g. if you use a mod that adds custom personality traits and try to play that save without the mod).
|
||||||
|
- Fixed sourcerect issue in alien generator + decorative sprite not disappearing when the fuel rod is taken out.
|
||||||
|
- Fixed corrupted mods causing a nullref exception when autodetecting required mods in the sub editor.
|
||||||
|
- Fixed minerals not disappearing from mineral scanner if they get detached by something else than a character picking them up (e.g. by the destructible ice wall they're on breaking).
|
||||||
|
- Fixed event-specific metal crate deconstructing to steel.
|
||||||
|
- Fixed inability to join servers that have enabled multiple mods with identical content.
|
||||||
|
- Fixed tandem fire not working if there's a character between you and the other character on a periscope.
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.19.11.0
|
v0.19.11.0
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -29,7 +29,17 @@ namespace TestProject
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void TestBitField()
|
public void TestBitField()
|
||||||
{
|
{
|
||||||
|
// 0-length bitfield test
|
||||||
|
SerializeDeserializeBitField(Array.Empty<bool>());
|
||||||
|
|
||||||
|
// Normal bitfield test
|
||||||
Prop.ForAll<bool[]>(SerializeDeserializeBitField).VerboseCheckThrowOnFailure();
|
Prop.ForAll<bool[]>(SerializeDeserializeBitField).VerboseCheckThrowOnFailure();
|
||||||
|
|
||||||
|
// Large bitfield test
|
||||||
|
Prop.ForAll(
|
||||||
|
Arb.Generate<bool[]>().Resize(1000).Where(arr => arr.Length >= 800)
|
||||||
|
.ToArbitrary(),
|
||||||
|
SerializeDeserializeBitField).VerboseCheckThrowOnFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -278,7 +288,7 @@ namespace TestProject
|
|||||||
private static void SerializeDeserializeBitField(bool[] arg)
|
private static void SerializeDeserializeBitField(bool[] arg)
|
||||||
{
|
{
|
||||||
ReadWriteMessage msg = new ReadWriteMessage();
|
ReadWriteMessage msg = new ReadWriteMessage();
|
||||||
IWritableBitField bitFieldWrite = new WriteOnlyBitField();
|
WriteOnlyBitField bitFieldWrite = new WriteOnlyBitField();
|
||||||
|
|
||||||
foreach (bool b in arg)
|
foreach (bool b in arg)
|
||||||
{
|
{
|
||||||
@@ -288,7 +298,7 @@ namespace TestProject
|
|||||||
bitFieldWrite.WriteToMessage(msg);
|
bitFieldWrite.WriteToMessage(msg);
|
||||||
msg.BitPosition = 0;
|
msg.BitPosition = 0;
|
||||||
|
|
||||||
IReadableBitField bitFieldRead = new ReadOnlyBitField(msg);
|
ReadOnlyBitField bitFieldRead = new ReadOnlyBitField(msg);
|
||||||
|
|
||||||
foreach (bool b in arg)
|
foreach (bool b in arg)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user