Unstable 0.1300.0.4

This commit is contained in:
Markus Isberg
2021-03-30 15:51:49 +03:00
parent 58c50a235d
commit 862221635c
108 changed files with 907 additions and 378 deletions

View File

@@ -251,7 +251,7 @@ namespace Barotrauma
/// </summary>
public bool Freeze { get; set; }
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true, bool? followSub = null)
{
prevPosition = position;
prevZoom = zoom;
@@ -278,7 +278,7 @@ namespace Barotrauma
velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
moveCam = velocity * moveSpeed * deltaTime * FreeCamMoveSpeed * 60.0f;
if (Screen.Selected == GameMain.GameScreen && FollowSub)
if (Screen.Selected == GameMain.GameScreen && (followSub ?? FollowSub))
{
var closestSub = Submarine.FindClosest(WorldViewCenter);
if (closestSub != null)
@@ -313,9 +313,10 @@ namespace Barotrauma
{
Vector2 mousePos = PlayerInput.MousePosition;
Vector2 offset = mousePos - Resolution.ToVector2() / 2;
offset.X = offset.X / (Resolution.X * 0.6f);
offset.Y = -offset.Y / (Resolution.Y * 0.6f);
offset.X = offset.X / (Resolution.X * 0.4f);
offset.Y = -offset.Y / (Resolution.Y * 0.3f);
if (offset.LengthSquared() > 1.0f) offset.Normalize();
float offsetUnscaledLen = offset.Length();
offset *= OffsetAmount;
// Freeze the camera movement by default, when the cursor is on top of an ui element.
// Setting a positive value to the OffsetAmount, will override this behaviour.
@@ -330,21 +331,20 @@ namespace Barotrauma
}
if (Freeze)
{
offset = previousOffset;
if (offset.LengthSquared() > 0.001f) { offset = previousOffset; }
}
else
{
previousOffset = offset;
}
//TODO: remove magic numbers
float minMultiplier = OffsetAmount > 0f ? ((DefaultZoom * 8f * 250f) / OffsetAmount) : 15f;
//how much to zoom out (0.0 = Default zoom, 1.0 = zoom completely out)
//how much to zoom out (zoom completely out when offset is 1000)
float zoomOutAmount = GetZoomAmount(offset);
float newZoom = MathHelper.Lerp(DefaultZoom, MinZoom * minMultiplier, zoomOutAmount) * globalZoomScale;
//scaled zoom amount
float scaledZoom = MathHelper.Lerp(DefaultZoom, MinZoom, zoomOutAmount) * globalZoomScale;
//zoom in further if zoomOutAmount is low and resolution is lower than reference
newZoom *= MathHelper.Lerp(0.5f * (1f - Math.Min(globalZoomScale, 1f)), 0f, zoomOutAmount) + 1f;
float newZoom = scaledZoom * (MathHelper.Lerp(0.3f * (1f - Math.Min(globalZoomScale, 1f)), 0f,
(GameMain.Config == null || GameMain.Config.EnableMouseLook) ? (float)Math.Sqrt(offsetUnscaledLen) : 0.3f) + 1f);
Zoom += (newZoom - zoom) / ZoomSmoothness;
@@ -416,7 +416,7 @@ namespace Barotrauma
private float GetZoomAmount(Vector2 offset)
{
return Math.Min(offset.Length() / Math.Max(1f, OffsetAmount), 1.0f);
return Math.Min(offset.Length() / 1000.0f, 1.0f);
}
public float GetZoomAmountFromPrevious()

View File

@@ -55,6 +55,11 @@ namespace Barotrauma
set
{
if (controlled == value) return;
if ((!(controlled is null)) && (!(Screen.Selected?.Cam is null)) && value is null)
{
Screen.Selected.Cam.TargetPos = Vector2.Zero;
Lights.LightManager.ViewTarget = null;
}
controlled = value;
if (controlled != null) controlled.Enabled = true;
CharacterHealth.OpenHealthWindow = null;
@@ -122,6 +127,9 @@ namespace Barotrauma
get { return gibEmitters; }
}
public static bool IsMouseOnUI => GUI.MouseOn != null ||
(CharacterInventory.IsMouseOnInventory() && !CharacterInventory.DraggingItemToWorld);
public class ObjectiveEntity
{
public Entity Entity;
@@ -291,6 +299,10 @@ namespace Barotrauma
cam.OffsetAmount = targetOffsetAmount = 0.0f;
}
}
else if (IsMouseOnUI)
{
targetOffsetAmount = cam.OffsetAmount;
}
else if (Vector2.DistanceSquared(AnimController.Limbs[0].SimPosition, mouseSimPos) > 1.0f)
{
Body body = Submarine.CheckVisibility(AnimController.Limbs[0].SimPosition, mouseSimPos);
@@ -417,6 +429,11 @@ namespace Barotrauma
GameMain.NetworkMember.AddChatMessage(chatMessage, ChatMessageType.Dead);
GameMain.LightManager.LosEnabled = false;
controlled = null;
if (!(Screen.Selected?.Cam is null))
{
Screen.Selected.Cam.TargetPos = Vector2.Zero;
Lights.LightManager.ViewTarget = null;
}
}
PlaySound(CharacterSound.SoundType.Die);
@@ -424,7 +441,15 @@ namespace Barotrauma
partial void DisposeProjSpecific()
{
if (controlled == this) controlled = null;
if (controlled == this)
{
controlled = null;
if (!(Screen.Selected?.Cam is null))
{
Screen.Selected.Cam.TargetPos = Vector2.Zero;
Lights.LightManager.ViewTarget = null;
}
}
if (GameMain.GameSession?.CrewManager != null &&
GameMain.GameSession.CrewManager.GetCharacters().Contains(this))

View File

@@ -12,6 +12,40 @@ namespace Barotrauma
{
class CharacterHUD
{
const float BossHealthBarDuration = 30.0f;
class BossHealthBar
{
public readonly Character Character;
public float FadeTimer;
public readonly GUIComponent TopContainer;
public readonly GUIComponent SideContainer;
public readonly GUIProgressBar TopHealthBar;
public readonly GUIProgressBar SideHealthBar;
public BossHealthBar(Character character)
{
Character = character;
FadeTimer = BossHealthBarDuration;
TopContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.18f, 0.03f), HUDFrame.RectTransform, Anchor.TopCenter)
{
MinSize = new Point(100, 50),
RelativeOffset = new Vector2(0.0f, 0.01f)
}, isHorizontal: false, childAnchor: Anchor.TopCenter);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), TopContainer.RectTransform), character.DisplayName, textAlignment: Alignment.Center, textColor: GUI.Style.Red);
TopHealthBar = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.6f), TopContainer.RectTransform), barSize: 0.0f, style: "CharacterHealthBarCentered");
SideContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), bossHealthContainer.RectTransform)
{
MinSize = new Point(80, 60)
}, isHorizontal: false, childAnchor: Anchor.TopRight);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), SideContainer.RectTransform), character.DisplayName, textAlignment: Alignment.CenterRight, textColor: GUI.Style.Red);
SideHealthBar = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.7f), SideContainer.RectTransform), barSize: 0.0f, style: "CharacterHealthBar");
}
}
private static readonly Dictionary<ISpatialEntity, int> orderIndicatorCount = new Dictionary<ISpatialEntity, int>();
const float ItemOverlayDelay = 1.0f;
private static Item focusedItem;
@@ -20,8 +54,12 @@ namespace Barotrauma
private static readonly List<Item> brokenItems = new List<Item>();
private static float brokenItemsCheckTimer;
private static readonly List<BossHealthBar> bossHealthBars = new List<BossHealthBar>();
private static readonly Dictionary<string, string> cachedHudTexts = new Dictionary<string, string>();
private static GUILayoutGroup bossHealthContainer;
private static GUIFrame hudFrame;
public static GUIFrame HUDFrame
{
@@ -34,6 +72,13 @@ namespace Barotrauma
{
CanBeFocused = false
};
bossHealthContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.15f, 0.5f), hudFrame.RectTransform, Anchor.CenterRight)
{
RelativeOffset = new Vector2(0.005f, 0.0f)
})
{
AbsoluteSpacing = GUI.IntScale(10)
};
}
return hudFrame;
}
@@ -71,7 +116,7 @@ namespace Barotrauma
public static void AddToGUIUpdateList(Character character)
{
if (GUI.DisableHUD) return;
if (GUI.DisableHUD) { return; }
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen)
{
@@ -84,7 +129,7 @@ namespace Barotrauma
foreach (ItemComponent ic in item.Components)
{
if (ic.DrawHudWhenEquipped) ic.AddToGUIUpdateList();
if (ic.DrawHudWhenEquipped) { ic.AddToGUIUpdateList(); }
}
}
}
@@ -100,13 +145,14 @@ namespace Barotrauma
public static void Update(float deltaTime, Character character, Camera cam)
{
UpdateBossHealthBars(deltaTime);
if (GUI.DisableHUD)
{
if (character.Inventory != null && !LockInventory(character))
{
character.Inventory.UpdateSlotInput();
}
return;
}
@@ -489,6 +535,92 @@ namespace Barotrauma
}
}
public static void ShowBossHealthBar(Character character)
{
var existingBar = bossHealthBars.Find(b => b.Character == character);
if (existingBar != null)
{
existingBar.FadeTimer = BossHealthBarDuration;
return;
}
if (bossHealthBars.Count > 5)
{
BossHealthBar oldestHealthBar = bossHealthBars.First();
foreach (var bar in bossHealthBars)
{
if (bar.TopHealthBar.BarSize < oldestHealthBar.TopHealthBar.BarSize)
{
oldestHealthBar = bar;
}
}
oldestHealthBar.FadeTimer = Math.Min(oldestHealthBar.FadeTimer, 1.0f);
}
bossHealthBars.Add(new BossHealthBar(character));
}
public static void UpdateBossHealthBars(float deltaTime)
{
for (int i = 0; i < bossHealthBars.Count; i++)
{
var bossHealthBar = bossHealthBars[i];
bool showTopBar = i == 0;
if (showTopBar != bossHealthBar.TopContainer.Visible)
{
bossHealthContainer.Recalculate();
}
bossHealthBar.TopContainer.Visible = showTopBar;
bossHealthBar.SideContainer.Visible = !bossHealthBar.TopContainer.Visible;
float health = bossHealthBar.Character.Vitality / bossHealthBar.Character.MaxVitality;
float alpha = Math.Min(bossHealthBar.FadeTimer, 1.0f);
foreach (var c in bossHealthBar.TopContainer.GetAllChildren())
{
c.Color = new Color(c.Color, (byte)(alpha * 255));
if (c is GUITextBlock textBlock)
{
textBlock.TextColor = new Color(textBlock.TextColor, (byte)(alpha * 255));
}
}
foreach (var c in bossHealthBar.SideContainer.GetAllChildren())
{
c.Color = new Color(c.Color, (byte)(alpha * 255));
if (c is GUITextBlock textBlock)
{
textBlock.TextColor = new Color(textBlock.TextColor, (byte)(alpha * 255));
}
}
bossHealthBar.TopHealthBar.BarSize = bossHealthBar.SideHealthBar.BarSize = health;
bossHealthBar.TopHealthBar.Color = bossHealthBar.SideHealthBar.Color =
ToolBox.GradientLerp(health, GUI.Style.HealthBarColorLow, GUI.Style.HealthBarColorMedium, GUI.Style.HealthBarColorHigh) * alpha;
if (bossHealthBar.Character.IsDead || bossHealthBar.Character.Removed)
{
bossHealthBar.FadeTimer = Math.Min(bossHealthBar.FadeTimer, 1.0f);
}
bossHealthBar.FadeTimer -= deltaTime;
}
for (int i = bossHealthBars.Count - 1; i >= 0 ; i--)
{
var bossHealthBar = bossHealthBars[i];
if (bossHealthBar.FadeTimer <= 0)
{
bossHealthBar.SideContainer.Parent?.RemoveChild(bossHealthBar.SideContainer);
bossHealthBar.TopContainer.Parent?.RemoveChild(bossHealthBar.TopContainer);
bossHealthBars.RemoveAt(i);
bossHealthContainer.Recalculate();
}
}
}
private static bool LockInventory(Character character)
{
if (character?.Inventory == null || !character.AllowInput || character.LockHands || IsCampaignInterfaceOpen) { return true; }

View File

@@ -297,6 +297,7 @@ namespace Barotrauma
barSize: 1.0f, color: GUI.Style.HealthBarColorHigh, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical")
{
HoverCursor = CursorState.Hand,
ToolTip = TextManager.GetWithVariable("hudbutton.healthinterface", "[key]", GameMain.Config.KeyBindText(InputType.Health)),
Enabled = true,
IsHorizontal = horizontal
};

View File

@@ -383,8 +383,20 @@ namespace Barotrauma
color: ((chatBox.Content.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f, parseRichText: true)
{
UserData = message.SenderName,
CanBeFocused = true
CanBeFocused = false
};
msgText.CalculateHeightFromText();
if (msgText.RichTextData != null)
{
foreach (var data in msgText.RichTextData)
{
msgText.ClickableAreas.Add(new GUITextBlock.ClickableArea()
{
Data = data,
OnClick = GameMain.NetLobbyScreen.SelectPlayer
});
}
}
if (message is OrderChatMessage orderChatMsg &&
Character.Controlled != null &&

View File

@@ -539,52 +539,42 @@ namespace Barotrauma
}
}
IEnumerable<string> strings;
if (MouseOn != null)
{
RectTransform mouseOnRect = MouseOn.RectTransform;
bool isAbsoluteOffsetInUse = mouseOnRect.AbsoluteOffset != Point.Zero || mouseOnRect.RelativeOffset == Vector2.Zero;
string selectedString = $"Selected UI Element: {MouseOn.GetType().Name} ({ MouseOn.Style?.Element.Name.LocalName ?? "no style" }, {MouseOn.Rect}";
string offsetString = $"Relative Offset: {mouseOnRect.RelativeOffset} | Absolute Offset: {(isAbsoluteOffsetInUse ? mouseOnRect.AbsoluteOffset : mouseOnRect.ParentRect.MultiplySize(mouseOnRect.RelativeOffset))}{(isAbsoluteOffsetInUse ? "" : " (Calculated from RelativeOffset)")}";
string anchorPivotString = $"Anchor: {mouseOnRect.Anchor} | Pivot: {mouseOnRect.Pivot}";
Vector2 selectedStringSize = SmallFont.MeasureString(selectedString);
Vector2 offsetStringSize = SmallFont.MeasureString(offsetString);
Vector2 anchorPivotStringSize = SmallFont.MeasureString(anchorPivotString);
int padding = IntScale(10);
int yPos = padding;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)selectedStringSize.X - padding, yPos), selectedString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)selectedStringSize.Y + padding / 2;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)offsetStringSize.X - padding, yPos), offsetString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)offsetStringSize.Y + padding / 2;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)anchorPivotStringSize.X - padding, yPos), anchorPivotString, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)anchorPivotStringSize.Y + padding / 2;
strings = new string[]
{
$"Selected UI Element: {MouseOn.GetType().Name} ({ MouseOn.Style?.Element.Name.LocalName ?? "no style" }, {MouseOn.Rect}",
$"Relative Offset: {mouseOnRect.RelativeOffset} | Absolute Offset: {(isAbsoluteOffsetInUse ? mouseOnRect.AbsoluteOffset : mouseOnRect.ParentRect.MultiplySize(mouseOnRect.RelativeOffset))}{(isAbsoluteOffsetInUse ? "" : " (Calculated from RelativeOffset)")}",
$"Anchor: {mouseOnRect.Anchor} | Pivot: {mouseOnRect.Pivot}"
};
}
else
{
string[] strings = new string[]
strings = new string[]
{
$"GUI.Scale: {Scale}",
$"GUI.xScale: {xScale}",
$"GUI.yScale: {yScale}",
$"RelativeHorizontalAspectRatio: {RelativeHorizontalAspectRatio}",
$"RelativeVerticalAspectRatio: {RelativeVerticalAspectRatio}",
$"Cam.Zoom: {Screen.Selected.Cam?.Zoom ?? 0f}",
};
}
int padding = IntScale(10);
int yPos = padding;
strings = strings.Concat(new string[] { $"Cam.Zoom: {Screen.Selected.Cam?.Zoom ?? 0f}" });
foreach (string str in strings)
{
Vector2 stringSize = SmallFont.MeasureString(str);
int padding = IntScale(10);
int yPos = padding;
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)stringSize.X - padding, yPos), str, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)stringSize.Y + padding / 2;
}
foreach (string str in strings)
{
Vector2 stringSize = SmallFont.MeasureString(str);
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - (int)stringSize.X - padding, yPos), str, Color.LightGreen, Color.Black, 0, SmallFont);
yPos += (int)stringSize.Y + padding / 2;
}
}
@@ -1037,7 +1027,7 @@ namespace Barotrauma
}
}
if (parent != null)
if (parent != null && parent.CanBeFocused)
{
if (!parent.Rect.Equals(monitorRect)) { return parent.HoverCursor; }
}

View File

@@ -573,8 +573,9 @@ namespace Barotrauma
{
base.Update(deltaTime);
if (ClickableAreas.Any() && (GUI.MouseOn?.IsParentOf(this) ?? true) && Rect.Contains(PlayerInput.MousePosition))
if (ClickableAreas.Any() && (GUI.MouseOn?.IsParentOf(this) ?? true))
{
if (!Rect.Contains(PlayerInput.MousePosition)) { return; }
int index = GetCaretIndexFromScreenPos(PlayerInput.MousePosition);
foreach (ClickableArea clickableArea in ClickableAreas)
{

View File

@@ -60,6 +60,7 @@ namespace Barotrauma
public GUITextBlock submarineFee;
public GUIButton selectSubmarineButton;
public GUITextBlock middleTextBlock;
public GUIButton previewButton;
}
public SubmarineSelection(bool transfer, Action closeAction, RectTransform parent)
@@ -191,6 +192,12 @@ namespace Barotrauma
submarineDisplayElement.submarineClass = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding + (int)GUI.Font.MeasureString(submarineDisplayElement.submarineName.Text).Y) }, string.Empty, textAlignment: Alignment.Center);
submarineDisplayElement.submarineFee = new GUITextBlock(new RectTransform(new Vector2(1f, 0.1f), submarineDisplayElement.background.RectTransform, Anchor.BottomCenter, Pivot.BottomCenter) { AbsoluteOffset = new Point(0, HUDLayoutSettings.Padding) }, string.Empty, textAlignment: Alignment.Center, font: GUI.SubHeadingFont);
submarineDisplayElement.selectSubmarineButton = new GUIButton(new RectTransform(Vector2.One, submarineDisplayElement.background.RectTransform), style: null);
submarineDisplayElement.previewButton = new GUIButton(new RectTransform(Vector2.One * 0.12f, submarineDisplayElement.background.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point((int)(0.03f * background.Rect.Height)) }, style: "ExpandButton")
{
Color = Color.White,
HoverColor = Color.White,
PressedColor = Color.White
};
submarineDisplays[i] = submarineDisplayElement;
}
@@ -299,6 +306,7 @@ namespace Barotrauma
submarineDisplays[i].selectSubmarineButton.OnClicked = null;
submarineDisplays[i].displayedSubmarine = null;
submarineDisplays[i].middleTextBlock.AutoDraw = false;
submarineDisplays[i].previewButton.Visible = false;
}
else
{
@@ -369,6 +377,13 @@ namespace Barotrauma
{
SelectSubmarine(subToDisplay, submarineDisplays[i].background.Rect);
}
submarineDisplays[i].previewButton.Visible = true;
submarineDisplays[i].previewButton.OnClicked = (btn, obj) =>
{
SubmarinePreview.Create(subToDisplay);
return false;
};
}
submarineIndex++;

View File

@@ -192,7 +192,7 @@ namespace Barotrauma
contentFrameSize = new Vector2(0.45f, 0.667f);
break;
}
contentFrame = new GUIFrame(new RectTransform(contentFrameSize, infoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { RelativeOffset = new Vector2(0.025f, 0.12f) });
contentFrame = new GUIFrame(new RectTransform(contentFrameSize, infoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.12f) });
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.958f, 0.943f), contentFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, GUI.IntScale(25f)) }, isHorizontal: true)
{
@@ -234,8 +234,6 @@ namespace Barotrauma
{
var reputationButton = createTabButton(InfoFrameTab.Reputation, "reputation");
var submarineButton = createTabButton(InfoFrameTab.Submarine, "submarine");
var balanceFrame = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, innerLayoutGroup.Rect.Height - infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), "", textAlignment: Alignment.Right, parseRichText: true)
{
@@ -251,6 +249,8 @@ namespace Barotrauma
}
}
var submarineButton = createTabButton(InfoFrameTab.Submarine, "submarine");
if (GameMain.NetworkMember != null)
{
var myCharacterButton = createTabButton(InfoFrameTab.MyCharacter, "tabmenu.character");
@@ -722,7 +722,7 @@ namespace Barotrauma
GUIComponent existingPreview = infoFrameHolder.FindChild("SelectedCharacter");
if (existingPreview != null) infoFrameHolder.RemoveChild(existingPreview);
GUIFrame background = new GUIFrame(new RectTransform(new Vector2(0.543f, 0.717f), infoFrameHolder.RectTransform, Anchor.TopLeft, Pivot.TopRight) { RelativeOffset = new Vector2(-0.061f, 0) })
GUIFrame background = new GUIFrame(new RectTransform(new Vector2(0.543f, 0.717f), infoFrameHolder.RectTransform, Anchor.TopLeft, Pivot.TopRight) { RelativeOffset = new Vector2(-0.145f, 0) })
{
UserData = "SelectedCharacter"
};
@@ -1106,7 +1106,11 @@ namespace Barotrauma
if (GameMain.GameSession?.GameMode is CampaignMode campaign)
{
var upgradeRootLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), true);
GUILayoutGroup headerLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.09f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0f, 0.43f) }, isHorizontal: true) { Stretch = true };
GUIImage headerIcon = new GUIImage(new RectTransform(Vector2.One, headerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "SubmarineIcon");
new GUITextBlock(new RectTransform(Vector2.One, headerLayout.RectTransform), TextManager.Get("uicategory.upgrades"), font: GUI.LargeFont);
var upgradeRootLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.48f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), isHorizontal: true);
var upgradeCategoryPanel = UpgradeStore.CreateUpgradeCategoryList(new RectTransform(new Vector2(0.4f, 1f), upgradeRootLayout.RectTransform));
upgradeCategoryPanel.HideChildrenOutsideFrame = true;
@@ -1129,6 +1133,11 @@ namespace Barotrauma
return true;
};
}
else
{
var specsListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.57f), paddedFrame.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft));
sub.Info.CreateSpecsWindow(specsListBox, GUI.Font, includeTitle: false, includeClass: false, includeDescription: true);
}
}
}
}

View File

@@ -767,6 +767,10 @@ namespace Barotrauma
else if (orderInfo.MatchesOrder(order, option))
{
icon.UserData = new OrderInfo(order, option, priority);
if (icon is GUIImage image)
{
image.Sprite = GetOrderIconSprite(order, option);
}
updatedExistingIcon = true;
}
}

View File

@@ -55,6 +55,10 @@ namespace Barotrauma
{
chatBox.ToggleOpen = wasChatBoxOpen;
}
if (!value && CampaignUI?.SelectedTab == InteractionType.PurchaseSub)
{
SubmarinePreview.Close();
}
showCampaignUI = value;
}
}

View File

@@ -533,7 +533,7 @@ namespace Barotrauma
base.Update(deltaTime);
Map?.Radiation.UpdateRadiation(deltaTime);
Map?.Radiation?.UpdateRadiation(deltaTime);
if (PlayerInput.SecondaryMouseButtonClicked() ||
PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))

View File

@@ -106,7 +106,7 @@ namespace Barotrauma
CheckIsInteracting();
CheckIfDivingGearOutOfOxygen();
CheckAdjacentHulls();
CheckHulls();
CheckReminders();
}
@@ -503,6 +503,19 @@ namespace Barotrauma
DisplayHint("onrepairfailed");
}
public static void OnActiveOrderAdded(Order order)
{
if (!CanDisplayHints()) { return; }
if (order == null) { return; }
if (order.Identifier == "reportballastflora" &&
order.TargetEntity is Hull h &&
h.Submarine?.TeamID == Character.Controlled.TeamID)
{
DisplayHint("onballastflorainfected");
}
}
private static void CheckIfDivingGearOutOfOxygen()
{
if (!CanDisplayHints()) { return; }
@@ -520,10 +533,14 @@ namespace Barotrauma
});
}
private static void CheckAdjacentHulls()
private static void CheckHulls()
{
if (!CanDisplayHints()) { return; }
if (Character.Controlled.CurrentHull == null) { return; }
if (HumanAIController.IsBallastFloraNoticeable(Character.Controlled, Character.Controlled.CurrentHull))
{
if (DisplayHint("onballastflorainfected")) { return; }
}
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
{
if (gap.ConnectedDoor == null || gap.ConnectedDoor.Impassable) { continue; }

View File

@@ -705,6 +705,7 @@ namespace Barotrauma.Items.Components
if (c.Params.HideInSonar) { continue; }
if (!c.IsUnconscious && c.Params.DistantSonarRange > 0.0f &&
c.AIController is EnemyAIController enemyAI && enemyAI.IsTargetingPlayer &&
((c.WorldPosition - transducerCenter) * displayScale).LengthSquared() > DisplayRadius * DisplayRadius)
{
float dist = Vector2.Distance(c.WorldPosition, transducerCenter);
@@ -1099,6 +1100,7 @@ namespace Barotrauma.Items.Components
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
if (dockingPort.Item.Submarine == null) { continue; }
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
if (!dockingPort.Item.Submarine.ShowSonarMarker && !dockingPort.Item.Submarine.Info.IsOutpost) { continue; }
//don't show the docking ports of the opposing team on the sonar
if (item.Submarine != null)

View File

@@ -238,7 +238,8 @@ namespace Barotrauma.Items.Components
if (!PlayerInput.PrimaryMouseButtonHeld())
{
if (GameMain.NetworkMember != null || panel.CheckCharacterSuccess(Character.Controlled))
if ((GameMain.NetworkMember != null || panel.CheckCharacterSuccess(Character.Controlled)) &&
Wires.Count(w => w != null) < MaxPlayerConnectableWires)
{
//find an empty cell for the new connection
int index = FindEmptyIndex();

View File

@@ -50,7 +50,8 @@ namespace Barotrauma.Items.Components
var textBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform), ciElement.Signal, style: "GUITextBoxNoIcon")
{
OverflowClip = true,
UserData = ciElement
UserData = ciElement,
MaxTextLength = ciElement.MaxTextLength
};
//reset size restrictions set by the Style to make sure the elements can fit the interface
textBox.RectTransform.MinSize = textBox.Frame.RectTransform.MinSize = new Point(0, 0);

View File

@@ -130,12 +130,15 @@ namespace Barotrauma.Items.Components
}
}
powerIndicator = new GUIProgressBar(new RectTransform(new Vector2(0.18f, 0.03f), GUI.Canvas, Anchor.TopCenter)
powerIndicator = new GUIProgressBar(new RectTransform(new Vector2(0.18f, 0.03f), GUI.Canvas, Anchor.BottomCenter)
{
MinSize = new Point(100,20),
MinSize = new Point(100, 20),
RelativeOffset = new Vector2(0.0f, 0.01f)
},
barSize: 0.0f, style: "DeviceProgressBar");
},
barSize: 0.0f, style: "DeviceProgressBar")
{
CanBeFocused = false
};
}
public override void Move(Vector2 amount)
@@ -497,9 +500,15 @@ namespace Barotrauma.Items.Components
foreach (MapEntity e in item.linkedTo)
{
if (!(e is Item linkedItem)) { continue; }
availableAmmo.AddRange(linkedItem.ContainedItems);
}
var itemContainer = linkedItem.GetComponent<ItemContainer>();
if (itemContainer == null) { continue; }
availableAmmo.AddRange(itemContainer.Inventory.AllItems);
for (int i = 0; i < itemContainer.Inventory.Capacity - itemContainer.Inventory.AllItems.Count(); i++)
{
availableAmmo.Add(null);
}
}
float chargeRate =
powerConsumption <= 0.0f ?
1.0f :
@@ -534,7 +543,7 @@ namespace Barotrauma.Items.Components
int spacing = 5;
int slotsPerRow = Math.Min(availableAmmo.Count, 6);
int totalWidth = slotSize.X * slotsPerRow + spacing * (slotsPerRow - 1);
Point invSlotPos = new Point(GameMain.GraphicsWidth / 2 - totalWidth / 2, (int)(60 * GUI.Scale));
Point invSlotPos = new Point(GameMain.GraphicsWidth / 2 - totalWidth / 2, powerIndicator.Rect.Y - (int)(75 * GUI.Scale));
for (int i = 0; i < availableAmmo.Count; i++)
{
// TODO: Optimize? Creates multiple new objects per frame?

View File

@@ -319,10 +319,10 @@ namespace Barotrauma
{
get
{
return DraggingItems.Any() &&
Character.Controlled != null &&
return Character.Controlled != null &&
Character.Controlled.SelectedConstruction == null &&
CharacterHealth.OpenHealthWindow == null;
CharacterHealth.OpenHealthWindow == null &&
DraggingItems.Any();
}
}

View File

@@ -496,8 +496,6 @@ namespace Barotrauma.Lights
if ((!LosEnabled || LosMode == LosMode.None) && !ObstructVision) return;
if (ViewTarget == null) return;
if (Character.Controlled == null) { DebugConsole.NewMessage("aaa", Color.Orange); }
graphics.SetRenderTarget(LosTexture);
if (ObstructVision)

View File

@@ -103,13 +103,6 @@ namespace Barotrauma
};
}
#endif
public Location CurrentDisplayLocation
{
get
{
return GameMain.GameSession.Campaign.CurrentDisplayLocation;
}
}
partial void InitProjectSpecific()
{
@@ -263,24 +256,26 @@ namespace Barotrauma
{
Rectangle rect = mapContainer.Rect;
if (CurrentDisplayLocation != null)
var currentDisplayLocation = GameMain.GameSession?.Campaign?.GetCurrentDisplayLocation();
if (currentDisplayLocation != null)
{
if (!CurrentDisplayLocation.Discovered)
if (!currentDisplayLocation.Discovered)
{
RemoveFogOfWar(CurrentDisplayLocation);
CurrentDisplayLocation.Discovered = true;
if (CurrentDisplayLocation.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
RemoveFogOfWar(currentDisplayLocation);
currentDisplayLocation.Discovered = true;
if (currentDisplayLocation.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
{
furthestDiscoveredLocation = CurrentDisplayLocation;
furthestDiscoveredLocation = currentDisplayLocation;
}
}
}
Vector2 currentPosition = CurrentDisplayLocation.MapPosition;
Vector2 currentPosition = currentDisplayLocation.MapPosition;
if (Level.Loaded?.Type == LevelData.LevelType.LocationConnection && Level.Loaded.StartLocation != null && Level.Loaded.EndLocation != null)
{
Vector2 startPos = CurrentDisplayLocation == Level.Loaded.StartLocation ? Level.Loaded.StartLocation.MapPosition : Level.Loaded.EndLocation.MapPosition;
int moveDir = CurrentDisplayLocation == Level.Loaded.StartLocation ? 1 : -1;
Vector2 startPos = currentDisplayLocation == Level.Loaded.StartLocation ? Level.Loaded.StartLocation.MapPosition : Level.Loaded.EndLocation.MapPosition;
int moveDir = currentDisplayLocation == Level.Loaded.StartLocation ? 1 : -1;
Vector2 diff = Level.Loaded.EndLocation.MapPosition - Level.Loaded.StartLocation.MapPosition;
currentPosition = startPos +
@@ -330,14 +325,14 @@ namespace Barotrauma
for (int i = 0; i < Locations.Count; i++)
{
Location location = Locations[i];
if (IsInFogOfWar(location) && !(CurrentDisplayLocation?.Connections.Any(c => c.Locations.Contains(location)) ?? false) && !GameMain.DebugDraw) { continue; }
if (IsInFogOfWar(location) && !(currentDisplayLocation?.Connections.Any(c => c.Locations.Contains(location)) ?? false) && !GameMain.DebugDraw) { continue; }
Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
if (!rect.Contains(pos)) { continue; }
Sprite locationSprite = location.IsCriticallyRadiated() ? location.Type.RadiationSprite ?? location.Type.Sprite : location.Type.Sprite;
float iconScale = generationParams.LocationIconSize / locationSprite.size.X;
if (location == CurrentDisplayLocation) { iconScale *= 1.2f; }
if (location == currentDisplayLocation) { iconScale *= 1.2f; }
Rectangle drawRect = locationSprite.SourceRect;
drawRect.Width = (int)(drawRect.Width * iconScale * zoom * 1.4f);
@@ -383,9 +378,9 @@ namespace Barotrauma
{
foreach (LocationConnection connection in Connections)
{
if (HighlightedLocation != CurrentDisplayLocation &&
if (HighlightedLocation != currentDisplayLocation &&
connection.Locations.Contains(HighlightedLocation) &&
connection.Locations.Contains(CurrentDisplayLocation))
connection.Locations.Contains(currentDisplayLocation))
{
if (PlayerInput.PrimaryMouseButtonClicked() &&
SelectedLocation != HighlightedLocation && HighlightedLocation != null)
@@ -418,13 +413,13 @@ namespace Barotrauma
{
if (PlayerInput.DoubleClicked() && HighlightedLocation != null)
{
var passedConnection = CurrentDisplayLocation.Connections.Find(c => c.OtherLocation(CurrentDisplayLocation) == HighlightedLocation);
var passedConnection = currentDisplayLocation.Connections.Find(c => c.OtherLocation(currentDisplayLocation) == HighlightedLocation);
if (passedConnection != null)
{
passedConnection.Passed = true;
}
Location prevLocation = CurrentDisplayLocation;
Location prevLocation = currentDisplayLocation;
CurrentLocation = HighlightedLocation;
Level.Loaded.DebugSetStartLocation(CurrentLocation);
Level.Loaded.DebugSetEndLocation(null);
@@ -436,7 +431,7 @@ namespace Barotrauma
{
CurrentLocation.CreateStore();
ProgressWorld();
Radiation.OnStep(1);
Radiation?.OnStep(1);
}
else
{
@@ -461,6 +456,7 @@ namespace Barotrauma
public void Draw(SpriteBatch spriteBatch, GUICustomComponent mapContainer)
{
tooltip = null;
var currentDisplayLocation = GameMain.GameSession?.Campaign?.GetCurrentDisplayLocation();
Rectangle rect = mapContainer.Rect;
@@ -531,14 +527,14 @@ namespace Barotrauma
float rawNoiseScale = 1.0f + PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
DrawNoise(spriteBatch, rect, rawNoiseScale);
Radiation.Draw(spriteBatch, rect, zoom);
Radiation?.Draw(spriteBatch, rect, zoom);
if (generationParams.ShowLocations)
{
foreach (LocationConnection connection in Connections)
{
if (IsInFogOfWar(connection.Locations[0]) && IsInFogOfWar(connection.Locations[1])) { continue; }
DrawConnection(spriteBatch, connection, rect, viewOffset);
DrawConnection(spriteBatch, connection, rect, viewOffset, currentDisplayLocation);
}
for (int i = 0; i < Locations.Count; i++)
@@ -557,12 +553,12 @@ namespace Barotrauma
Color color = location.Type.SpriteColor;
if (!location.Discovered) { color = Color.White; }
if (location.Connections.Find(c => c.Locations.Contains(CurrentDisplayLocation)) == null)
if (location.Connections.Find(c => c.Locations.Contains(currentDisplayLocation)) == null)
{
color *= 0.5f;
}
float iconScale = location == CurrentDisplayLocation ? 1.2f : 1.0f;
float iconScale = location == currentDisplayLocation ? 1.2f : 1.0f;
if (location == HighlightedLocation)
{
iconScale *= 1.2f;
@@ -571,7 +567,7 @@ namespace Barotrauma
locationSprite.Draw(spriteBatch, pos, color,
scale: generationParams.LocationIconSize / locationSprite.size.X * iconScale * zoom);
if (location == CurrentDisplayLocation)
if (location == currentDisplayLocation)
{
if (SelectedLocation != null)
{
@@ -701,7 +697,7 @@ namespace Barotrauma
if (drawRadiationTooltip)
{
Radiation.DrawFront(spriteBatch);
Radiation?.DrawFront(spriteBatch);
}
spriteBatch.End();
@@ -736,7 +732,7 @@ namespace Barotrauma
private static float GetPerlinNoise() => PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
private void DrawConnection(SpriteBatch spriteBatch, LocationConnection connection, Rectangle viewArea, Vector2 viewOffset, Color? overrideColor = null)
private void DrawConnection(SpriteBatch spriteBatch, LocationConnection connection, Rectangle viewArea, Vector2 viewOffset, Location currentDisplayLocation, Color? overrideColor = null)
{
Color connectionColor;
if (GameMain.DebugDraw)
@@ -765,15 +761,15 @@ namespace Barotrauma
width = (int)(width * 1.5f);
}
//selected connection
if (SelectedLocation != CurrentDisplayLocation &&
connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
if (SelectedLocation != currentDisplayLocation &&
connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(currentDisplayLocation))
{
connectionColor = generationParams.HighlightedConnectionColor;
width *= 2;
}
//highlighted connection
else if (HighlightedLocation != CurrentDisplayLocation &&
connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
else if (HighlightedLocation != currentDisplayLocation &&
connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(currentDisplayLocation))
{
connectionColor = generationParams.HighlightedConnectionColor;
width *= 2;
@@ -834,7 +830,7 @@ namespace Barotrauma
if (connection == SelectedConnection)
{
float t = (i - startIndex) / (float)(endIndex - startIndex - 1);
if (CurrentDisplayLocation == connection.Locations[1]) { t = 1.0f - t; }
if (currentDisplayLocation == connection.Locations[1]) { t = 1.0f - t; }
if (t > connectionHighlightState)
{
segmentWidth /= 2;

View File

@@ -20,7 +20,7 @@ namespace Barotrauma
{
var texture = TextureLoader.FromStream(mem, path: FilePath, compress: false);
if (texture == null) { throw new Exception("PreviewImage texture returned null"); }
PreviewImage = new Sprite(texture, null, null);
PreviewImage = new Sprite(texture, sourceRectangle: null, newOffset: null, path: FilePath);
}
}
catch (Exception e)
@@ -39,6 +39,7 @@ namespace Barotrauma
var previewButton = new GUIButton(new RectTransform(new Vector2(1f, 0.5f), content.RectTransform), style: null)
{
CanBeFocused = SubmarineElement != null,
OnClicked = (btn, obj) => { SubmarinePreview.Create(this); return false; },
};
@@ -61,16 +62,19 @@ namespace Barotrauma
new GUIFrame(new RectTransform(Vector2.One, submarinePreviewBackground.RectTransform), "InnerGlow", color: Color.Black) { CanBeFocused = false };
}
new GUIFrame(new RectTransform(Vector2.One * 0.12f, previewButton.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight)
if (SubmarineElement != null)
{
AbsoluteOffset = new Point((int)(0.03f * previewButton.Rect.Height))
},
"ExpandButton", Color.White)
{
Color = Color.White,
HoverColor = Color.White,
PressedColor = Color.White
};
new GUIFrame(new RectTransform(Vector2.One * 0.12f, previewButton.RectTransform, anchor: Anchor.BottomRight, pivot: Pivot.BottomRight, scaleBasis: ScaleBasis.BothHeight)
{
AbsoluteOffset = new Point((int)(0.03f * previewButton.Rect.Height))
},
"ExpandButton", Color.White)
{
Color = Color.White,
HoverColor = Color.White,
PressedColor = Color.White
};
}
var descriptionBox = new GUIListBox(new RectTransform(new Vector2(1, 0.5f), content.RectTransform, Anchor.BottomCenter))
{
@@ -81,10 +85,10 @@ namespace Barotrauma
ScalableFont font = parent.Rect.Width < 350 ? GUI.SmallFont : GUI.Font;
CreateSpecsWindow(descriptionBox, font, includesDescription: true);
CreateSpecsWindow(descriptionBox, font, includeDescription: true);
}
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font, bool includeTitle = true, bool includesDescription = false)
public void CreateSpecsWindow(GUIListBox parent, ScalableFont font, bool includeTitle = true, bool includeClass = true, bool includeDescription = false)
{
float leftPanelWidth = 0.6f;
float rightPanelWidth = 0.4f;
@@ -94,15 +98,18 @@ namespace Barotrauma
int leftPanelWidthInt = (int)(parent.Rect.Width * leftPanelWidth);
GUITextBlock submarineNameText = null;
GUITextBlock submarineClassText = null;
if (includeTitle)
{
int nameHeight = (int)GUI.LargeFont.MeasureString(DisplayName, true).Y;
submarineNameText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, nameHeight + HUDLayoutSettings.Padding / 2), parent.Content.RectTransform), DisplayName, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) { CanBeFocused = false };
submarineNameText.RectTransform.MinSize = new Point(0, (int)submarineNameText.TextSize.Y);
}
var submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
if (includeClass)
{
submarineClassText = new GUITextBlock(new RectTransform(new Point(leftPanelWidthInt, classHeight), parent.Content.RectTransform), className, textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) { CanBeFocused = false };
submarineClassText.RectTransform.MinSize = new Point(0, (int)submarineClassText.TextSize.Y);
}
Vector2 realWorldDimensions = Dimensions * Physics.DisplayToRealWorldRatio;
if (realWorldDimensions != Vector2.Zero)
{
@@ -169,7 +176,7 @@ namespace Barotrauma
}
GUITextBlock descBlock = null;
if (includesDescription)
if (includeDescription)
{
//space
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), parent.Content.RectTransform), style: null);

View File

@@ -60,10 +60,15 @@ namespace Barotrauma
public static void Create(SubmarineInfo submarineInfo)
{
instance?.Dispose();
Close();
instance = new SubmarinePreview(submarineInfo);
}
public static void Close()
{
instance?.Dispose();
}
private SubmarinePreview(SubmarineInfo subInfo)
{
camera = new Camera();
@@ -102,7 +107,7 @@ namespace Barotrauma
},
(deltaTime, component) => {
bool isMouseOnComponent = GUI.MouseOn == component;
camera.MoveCamera(deltaTime, allowZoom: isMouseOnComponent);
camera.MoveCamera(deltaTime, allowZoom: isMouseOnComponent, followSub: false);
if (isMouseOnComponent &&
(PlayerInput.MidButtonHeld() || PlayerInput.LeftButtonHeld()))
{
@@ -136,7 +141,7 @@ namespace Barotrauma
ScrollBarVisible = false,
Spacing = 5
};
subInfo.CreateSpecsWindow(specsContainer, GUI.Font, includeTitle: false, includesDescription: true);
subInfo.CreateSpecsWindow(specsContainer, GUI.Font, includeTitle: false, includeDescription: true);
int width = specsContainer.Rect.Width;
void recalculateSpecsContainerHeight()
{

View File

@@ -29,6 +29,14 @@ namespace Barotrauma.Networking
string senderName = msg.ReadString();
Character senderCharacter = null;
Client senderClient = null;
bool hasSenderClient = msg.ReadBoolean();
if (hasSenderClient)
{
UInt64 clientId = msg.ReadUInt64();
senderClient = GameMain.Client.ConnectedClients.Find(c => c.SteamID == clientId || c.ID == clientId);
if (senderClient != null) { senderName = senderClient.Name; }
}
bool hasSenderCharacter = msg.ReadBoolean();
if (hasSenderCharacter)
{
@@ -38,6 +46,7 @@ namespace Barotrauma.Networking
senderName = senderCharacter.Name;
}
}
msg.ReadPadBits();
switch (type)
{
@@ -197,7 +206,7 @@ namespace Barotrauma.Networking
GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
break;
default:
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter, changeType);
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType);
break;
}
LastID = id;

View File

@@ -1805,8 +1805,10 @@ namespace Barotrauma.Networking
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
if (matchingSub == null)
{
matchingSub = new SubmarineInfo(Path.Combine(SubmarineInfo.SavePath, subName) + ".sub", subHash, tryLoad: false);
matchingSub.SubmarineClass = (SubmarineClass)subClass;
matchingSub = new SubmarineInfo(Path.Combine(SubmarineInfo.SavePath, subName) + ".sub", subHash, tryLoad: false)
{
SubmarineClass = (SubmarineClass)subClass
};
}
matchingSub.RequiredContentPackagesInstalled = requiredContentPackagesInstalled;
ServerSubmarines.Add(matchingSub);
@@ -3578,6 +3580,10 @@ namespace Barotrauma.Networking
{
errorLines.Add("Submarine: " + GameMain.GameSession.Submarine.Info.Name);
}
if (GameMain.NetworkMember?.RespawnManager?.RespawnShuttle != null)
{
errorLines.Add("Respawn shuttle: " + GameMain.NetworkMember.RespawnManager.RespawnShuttle.Info.Name);
}
if (Level.Loaded != null)
{
errorLines.Add("Level: " + Level.Loaded.Seed + ", " + string.Join(", ", Level.Loaded.EqualityCheckValues.Select(cv => cv.ToString("X"))));

View File

@@ -648,7 +648,14 @@ namespace Barotrauma.Networking
foreach (ItemPrefab ip in ItemPrefab.Prefabs)
{
if (!ip.CanBeBought && !ip.Tags.Contains("smallitem")) continue;
if (ip.AllowAsExtraCargo.HasValue)
{
if (!ip.AllowAsExtraCargo.Value) { continue; }
}
else
{
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)
{

View File

@@ -112,14 +112,17 @@ namespace Barotrauma
switch (voteType)
{
case VoteType.Sub:
SubmarineInfo sub = data as SubmarineInfo;
if (sub == null) { return; }
case VoteType.Sub:
if (!(data is SubmarineInfo sub)) { return; }
msg.Write(sub.EqualityCheckVal);
if (sub.EqualityCheckVal == 0)
{
//sub doesn't exist client-side, use hash to let the server know which one we voted for
msg.Write(sub.MD5Hash.Hash);
}
break;
case VoteType.Mode:
GameModePreset gameMode = data as GameModePreset;
if (gameMode == null) { return; }
if (!(data is GameModePreset gameMode)) { return; }
msg.Write(gameMode.Identifier);
break;
case VoteType.EndRound:
@@ -127,8 +130,7 @@ namespace Barotrauma
msg.Write((bool)data);
break;
case VoteType.Kick:
Client votedClient = data as Client;
if (votedClient == null) return;
if (!(data is Client votedClient)) { return; }
msg.Write(votedClient.ID);
break;

View File

@@ -173,7 +173,15 @@ namespace Barotrauma
string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
CampaignSettings settings = new CampaignSettings { RadiationEnabled = EnableRadiationToggle?.Selected ?? GameMain.NetLobbyScreen.IsRadiationEnabled() };
CampaignSettings settings = new CampaignSettings();
if (isMultiplayer)
{
settings.RadiationEnabled = GameMain.NetLobbyScreen.IsRadiationEnabled();
}
else
{
settings.RadiationEnabled = EnableRadiationToggle?.Selected ?? false;
}
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
{
@@ -257,11 +265,14 @@ namespace Barotrauma
if (!isMultiplayer)
{
EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 1f), buttonContainer.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
if (MapGenerationParams.Instance.RadiationParams != null)
{
Selected = true,
ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip")
};
EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 1f), buttonContainer.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
{
Selected = true,
ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip")
};
}
var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(5) }, style: "GUINotificationButton")
{

View File

@@ -306,7 +306,7 @@ namespace Barotrauma
{
var map = GameMain.GameSession?.Map;
if (map == null) { return; }
if (selectedLocation != null && selectedLocation == map.CurrentDisplayLocation)
if (selectedLocation != null && selectedLocation == GameMain.GameSession.Campaign.GetCurrentDisplayLocation())
{
map.SelectLocation(-1);
}
@@ -438,7 +438,7 @@ namespace Barotrauma
};
SelectedLevel = connection?.LevelData;
Location currentDisplayLocation = Campaign.CurrentDisplayLocation;
Location currentDisplayLocation = Campaign.GetCurrentDisplayLocation();
if (connection != null && connection.Locations.Contains(currentDisplayLocation))
{
List<Mission> availableMissions = currentDisplayLocation.GetMissionsInConnection(connection).ToList();

View File

@@ -711,7 +711,7 @@ namespace Barotrauma.CharacterEditor
}
}
// Camera
Cam.MoveCamera((float)deltaTime, allowMove: false);
Cam.MoveCamera((float)deltaTime, allowMove: false, allowZoom: GUI.MouseOn == null);
Vector2 targetPos = character.WorldPosition;
if (PlayerInput.MidButtonHeld())
{

View File

@@ -953,7 +953,7 @@ namespace Barotrauma
CreateGUI();
}
Cam.MoveCamera((float) deltaTime, true, true);
Cam.MoveCamera((float) deltaTime, allowMove: true, allowZoom: GUI.MouseOn == null);
Vector2 mousePos = Cam.ScreenToWorld(PlayerInput.MousePosition);
mousePos.Y = -mousePos.Y;

View File

@@ -843,7 +843,7 @@ namespace Barotrauma
pointerLightSource.Position = cam.ScreenToWorld(PlayerInput.MousePosition);
pointerLightSource.Enabled = cursorLightEnabled.Selected;
pointerLightSource.IsBackground = true;
cam.MoveCamera((float)deltaTime);
cam.MoveCamera((float)deltaTime, allowZoom: GUI.MouseOn == null);
cam.UpdateTransform();
Level.Loaded?.Update((float)deltaTime, cam);

View File

@@ -1173,7 +1173,10 @@ namespace Barotrauma
(int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f),
campaignSetupUI.StartButton.RectTransform.MinSize.Y);
startButtonContainer.RectTransform.MinSize = new Point(0, campaignSetupUI.StartButton.RectTransform.MinSize.Y);
campaignSetupUI.EnableRadiationToggle.RectTransform.Parent = startButtonContainer.RectTransform;
if (campaignSetupUI.EnableRadiationToggle != null)
{
campaignSetupUI.EnableRadiationToggle.RectTransform.Parent = startButtonContainer.RectTransform;
}
campaignSetupUI.InitialMoneyText.RectTransform.Parent = startButtonContainer.RectTransform;
}

View File

@@ -485,6 +485,7 @@ namespace Barotrauma
if (socialHolder != null) { socialHolder.Visible = false; }
if (!(serverLogHolder?.Visible ?? true))
{
if (GameMain.Client?.ServerSettings?.ServerLog == null) { return false; }
serverLogHolder.Visible = true;
GameMain.Client.ServerSettings.ServerLog.AssignLogFrame(serverLogReverseButton, serverLogBox, serverLogFilterTicks.Content, serverLogFilter);
}
@@ -1134,15 +1135,19 @@ namespace Barotrauma
}
};
radiationEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), settingsContent.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
if (MapGenerationParams.Instance.RadiationParams != null)
{
Selected = true,
OnSelected = box =>
radiationEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), settingsContent.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
{
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, radiationEnabled: box.Selected);
return true;
}
};
Selected = true,
OnSelected = box =>
{
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, radiationEnabled: box.Selected);
return true;
}
};
}
List<GUIComponent> settingsElements = settingsContent.Children.ToList();
for (int i = 0; i < settingsElements.Count; i++)
@@ -1292,7 +1297,10 @@ namespace Barotrauma
}
SeedBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
levelDifficultyScrollBar.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
radiationEnabledTickBox.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
if (radiationEnabledTickBox != null)
{
radiationEnabledTickBox.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
}
traitorProbabilityButtons[0].Enabled = traitorProbabilityButtons[1].Enabled = traitorProbabilityText.Enabled =
!CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
botCountButtons[0].Enabled = botCountButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
@@ -2611,6 +2619,18 @@ namespace Barotrauma
UserData = message,
CanBeFocused = false
};
msg.CalculateHeightFromText();
if (msg.RichTextData != null)
{
foreach (var data in msg.RichTextData)
{
msg.ClickableAreas.Add(new GUITextBlock.ClickableArea()
{
Data = data,
OnClick = GameMain.NetLobbyScreen.SelectPlayer
});
}
}
msg.RectTransform.SizeChanged += Recalculate;
void Recalculate()
{

View File

@@ -311,7 +311,7 @@ namespace Barotrauma
public override void Update(double deltaTime)
{
cam.MoveCamera((float)deltaTime, true);
cam.MoveCamera((float)deltaTime, allowMove: true, allowZoom: GUI.MouseOn == null);
if (selectedPrefab != null)
{

View File

@@ -4291,7 +4291,7 @@ namespace Barotrauma
if (PlayerInput.IsCtrlDown() && MapEntity.StartMovingPos == Vector2.Zero)
{
cam.MoveCamera((float) deltaTime, allowMove: false);
cam.MoveCamera((float) deltaTime, allowMove: false, allowZoom: GUI.MouseOn == null);
// Save menu
if (PlayerInput.KeyHit(Keys.S))
{
@@ -4330,12 +4330,12 @@ namespace Barotrauma
}
else
{
cam.MoveCamera((float) deltaTime, allowMove: true);
cam.MoveCamera((float) deltaTime, allowMove: true, allowZoom: GUI.MouseOn == null);
}
}
else
{
cam.MoveCamera((float) deltaTime, allowMove: false);
cam.MoveCamera((float) deltaTime, allowMove: false, allowZoom: GUI.MouseOn == null);
}
if (PlayerInput.MidButtonHeld())

View File

@@ -105,7 +105,7 @@ namespace Barotrauma.Sounds
int alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set buffer data for non-streamed audio! " + Al.GetErrorString(alError));
throw new Exception("Failed to set regular buffer data for non-streamed audio! " + Al.GetErrorString(alError));
}
MuffleBuffer(floatBuffer, SampleRate, reader.Channels);
@@ -118,7 +118,7 @@ namespace Barotrauma.Sounds
alError = Al.GetError();
if (alError != Al.NoError)
{
throw new Exception("Failed to set buffer data for non-streamed audio! " + Al.GetErrorString(alError));
throw new Exception("Failed to set muffled buffer data for non-streamed audio! " + Al.GetErrorString(alError));
}
reader.Dispose(); reader = null;

View File

@@ -34,6 +34,7 @@ namespace Barotrauma.Sounds
{
bufferPool.ForEach(b => Al.DeleteBuffer(b));
bufferPool.Clear();
BuffersGenerated = 0;
}
public bool RequestAlBuffers()
@@ -81,10 +82,37 @@ namespace Barotrauma.Sounds
if (otherSound.IsPlaying()) { continue; }
if (otherSound.Buffers == null) { continue; }
if (otherSound.Buffers.AlBuffer == 0) { continue; }
// Dispose all channels that are holding
// a reference to these buffers, otherwise
// an INVALID_OPERATION error will be thrown
// when attempting to set the buffer data later.
// Having the sources not play is not enough,
// as OpenAL assumes that you may want to call
// alSourcePlay without reassigning the buffer.
otherSound.Owner.KillChannels(otherSound);
AlBuffer = otherSound.Buffers.AlBuffer;
AlMuffledBuffer = otherSound.Buffers.AlMuffledBuffer;
otherSound.Buffers.AlBuffer = 0;
otherSound.Buffers.AlMuffledBuffer = 0;
// For performance reasons, sift the current sound to
// the end of the loadedSounds list, that way it'll
// be less likely to have its buffers stolen, which
// means less reuploads for frequently played sounds.
sound.Owner.MoveSoundToPosition(sound, sound.Owner.LoadedSoundCount-1);
if (!Al.IsBuffer(AlBuffer))
{
throw new Exception(sound.Filename + " has an invalid buffer!");
}
if (!Al.IsBuffer(AlMuffledBuffer))
{
throw new Exception(sound.Filename + " has an invalid muffled buffer!");
}
return true;
}

View File

@@ -491,8 +491,10 @@ namespace Barotrauma.Sounds
mutex = new object();
}
#if !DEBUG
try
{
#endif
if (mutex != null) { Monitor.Enter(mutex); }
if (sound.Owner.CountPlayingInstances(sound) < sound.MaxSimultaneousInstances)
{
@@ -515,15 +517,6 @@ namespace Barotrauma.Sounds
Sound.FillBuffers();
}
if (!Al.IsBuffer(sound.Buffers.AlBuffer))
{
throw new Exception(sound.Filename + " has an invalid buffer!");
}
if (!Al.IsBuffer(sound.Buffers.AlMuffledBuffer))
{
throw new Exception(sound.Filename + " has an invalid muffled buffer!");
}
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffled ? Sound.Buffers.AlMuffledBuffer : Sound.Buffers.AlBuffer;
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
alError = Al.GetError();
@@ -587,6 +580,7 @@ namespace Barotrauma.Sounds
this.Near = near;
this.Far = far;
this.Category = category;
#if !DEBUG
}
catch
{
@@ -594,8 +588,11 @@ namespace Barotrauma.Sounds
}
finally
{
#endif
if (mutex != null) { Monitor.Exit(mutex); }
#if !DEBUG
}
#endif
Sound.Owner.Update();
}

View File

@@ -514,6 +514,18 @@ namespace Barotrauma.Sounds
}
}
public void MoveSoundToPosition(Sound sound, int pos)
{
lock (loadedSounds)
{
int index = loadedSounds.IndexOf(sound);
if (index >= 0)
{
loadedSounds.SiftElement(index, pos);
}
}
}
public void SetCategoryGainMultiplier(string category, float gain, int index=0)
{
if (Disabled) { return; }

View File

@@ -29,7 +29,16 @@ namespace Barotrauma
get { return texture != null && !cannotBeLoaded; }
}
public Sprite(Texture2D texture, Rectangle? sourceRectangle, Vector2? newOffset, float newRotation = 0.0f)
public Sprite(Sprite other) : this(other.texture, other.sourceRect, other.offset, other.rotation)
{
FilePath = other.FilePath;
FullPath = other.FullPath;
Compress = other.Compress;
size = other.size;
effects = other.effects;
}
public Sprite(Texture2D texture, Rectangle? sourceRectangle, Vector2? newOffset, float newRotation = 0.0f, string path = null)
{
this.texture = texture;
@@ -45,6 +54,8 @@ namespace Barotrauma
rotation = newRotation;
FilePath = path;
AddToList(this);
}

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.3</Version>
<Version>0.1300.0.4</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.3</Version>
<Version>0.1300.0.4</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product>
<Version>0.1300.0.3</Version>
<Version>0.1300.0.4</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.3</Version>
<Version>0.1300.0.4</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.3</Version>
<Version>0.1300.0.4</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -367,7 +367,7 @@ namespace Barotrauma
{
if (CoroutineManager.IsCoroutineRunning("LevelTransition")) { return; }
Map?.Radiation.UpdateRadiation(deltaTime);
Map?.Radiation?.UpdateRadiation(deltaTime);
base.Update(deltaTime);
if (Level.Loaded != null)

View File

@@ -230,12 +230,16 @@ namespace Barotrauma.Networking
2 + //(UInt16)NetStateID
1 + //(byte)Type
Encoding.UTF8.GetBytes(Text).Length + 2;
if (SenderClient != null)
{
length += 8; //SteamID or local ID (ulong)
}
if (Sender != null && c.InGame)
{
length += 2; //sender ID (UInt16)
}
else if (SenderName != null)
if (SenderName != null)
{
length += Encoding.UTF8.GetBytes(SenderName).Length + 2;
}
@@ -252,11 +256,16 @@ namespace Barotrauma.Networking
msg.Write(Text);
msg.Write(SenderName);
msg.Write(SenderClient != null);
msg.Write(SenderClient != null ?
((SenderClient.SteamID != 0) ? SenderClient.SteamID : SenderClient.ID) :
0);
msg.Write(Sender != null && c.InGame);
if (Sender != null && c.InGame)
{
msg.Write(Sender.ID);
}
msg.WritePadBits();
if (Type == ChatMessageType.ServerMessageBoxInGame)
{
msg.Write(IconStyle);

View File

@@ -938,6 +938,10 @@ namespace Barotrauma.Networking
{
errorLines.Add("Submarine: " + GameMain.GameSession.Submarine.Info.Name);
}
if (GameMain.NetworkMember?.RespawnManager?.RespawnShuttle != null)
{
errorLines.Add("Respawn shuttle: " + GameMain.NetworkMember.RespawnManager.RespawnShuttle.Info.Name);
}
if (Level.Loaded != null)
{
errorLines.Add("Level: " + Level.Loaded.Seed + ", " + string.Join(", ", Level.Loaded.EqualityCheckValues.Select(cv => cv.ToString("X"))));
@@ -3111,7 +3115,7 @@ namespace Barotrauma.Networking
string myReceivedMessage = type == ChatMessageType.Server || type == ChatMessageType.Error ? TextManager.GetServerMessage(message) : message;
if (!string.IsNullOrWhiteSpace(myReceivedMessage))
{
AddChatMessage(myReceivedMessage, (ChatMessageType)type, senderName, senderCharacter);
AddChatMessage(myReceivedMessage, (ChatMessageType)type, senderName, senderClient, senderCharacter);
}
}
}
@@ -3778,18 +3782,6 @@ namespace Barotrauma.Networking
}
}
public static string ClientLogName(Client client, string name = null)
{
if (client == null) { return name; }
string retVal = "‖";
if (client.Karma < 40.0f)
{
retVal += "color:#ff9900;";
}
retVal += "metadata:" + (client.SteamID != 0 ? client.SteamID.ToString() : client.ID.ToString()) + "‖" + (name ?? client.Name).Replace("‖","") + "‖end‖";
return retVal;
}
public static string CharacterLogName(Character character)
{
if (character == null) { return "[NULL]"; }

View File

@@ -8,11 +8,16 @@
msg.Write(NetStateID);
msg.Write((byte)ChatMessageType.Order);
msg.Write(SenderName);
msg.Write(SenderClient != null);
msg.Write(SenderClient != null ?
((SenderClient.SteamID != 0) ? SenderClient.SteamID : SenderClient.ID) :
0);
msg.Write(Sender != null && c.InGame);
if (Sender != null && c.InGame)
{
msg.Write(Sender.ID);
}
msg.WritePadBits();
WriteOrder(msg);
}
}

View File

@@ -212,7 +212,7 @@ namespace Barotrauma.Networking
return;
}
if (connectedClients.Count >= serverSettings.MaxPlayers - 1)
if (connectedClients.Count >= serverSettings.MaxPlayers)
{
RemovePendingClient(pendingClient, DisconnectReason.ServerFull, "");
}

View File

@@ -65,7 +65,7 @@ namespace Barotrauma
public void ServerRead(IReadMessage inc, Client sender)
{
if (GameMain.Server == null || sender == null) return;
if (GameMain.Server == null || sender == null) { return; }
byte voteTypeByte = inc.ReadByte();
VoteType voteType = VoteType.Unknown;
@@ -83,7 +83,10 @@ namespace Barotrauma
{
case VoteType.Sub:
int equalityCheckVal = inc.ReadInt32();
SubmarineInfo sub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.EqualityCheckVal == equalityCheckVal);
string hash = equalityCheckVal > 0 ? string.Empty : inc.ReadString();
SubmarineInfo sub = equalityCheckVal > 0 ?
SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Type == SubmarineType.Player && s.EqualityCheckVal == equalityCheckVal) :
SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Type == SubmarineType.Player && s.MD5Hash.Hash == hash);
sender.SetVote(voteType, sub);
break;
case VoteType.Mode:

View File

@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product>
<Version>0.1300.0.3</Version>
<Version>0.1300.0.4</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName>

View File

@@ -265,16 +265,22 @@ namespace Barotrauma
}
}
public void UnequipEmptyItems(Item item, bool avoidDroppingInSea = true) => UnequipEmptyItems(Character, item, avoidDroppingInSea);
public void UnequipEmptyItems(Item parentItem, bool avoidDroppingInSea = true) => UnequipEmptyItems(Character, parentItem, avoidDroppingInSea);
public static void UnequipEmptyItems(Character character, Item item, bool avoidDroppingInSea = true)
public void UnequipContainedItems(Item parentItem, Func<Item, bool> predicate, bool avoidDroppingInSea = true) => UnequipContainedItems(Character, parentItem, predicate, avoidDroppingInSea);
public static void UnequipEmptyItems(Character character, Item parentItem, bool avoidDroppingInSea = true) => UnequipContainedItems(character, parentItem, it => it.Condition <= 0, avoidDroppingInSea);
public static void UnequipContainedItems(Character character, Item parentItem, Func<Item, bool> predicate, bool avoidDroppingInSea = true)
{
if (item.OwnInventory.AllItems.Any(it => it.Condition <= 0.0f))
var inventory = parentItem.OwnInventory;
if (inventory == null) { return; }
if (inventory.AllItems.Any(predicate))
{
foreach (Item containedItem in item.OwnInventory.AllItemsMod)
foreach (Item containedItem in inventory.AllItemsMod)
{
if (containedItem == null) { continue; }
if (containedItem.Condition <= 0.0f)
if (predicate(containedItem))
{
if (character.Submarine == null && avoidDroppingInSea)
{

View File

@@ -181,6 +181,7 @@ namespace Barotrauma
private set;
} = new HashSet<Submarine>();
public bool IsTargetingPlayer => SelectedAiTarget?.Entity?.Submarine != null && SelectedAiTarget.Entity.Submarine.Info.IsPlayer || SelectedAiTarget?.Entity is Character targetCharacter && targetCharacter.IsPlayer;
public bool IsBeingChasedBy(Character c) => c.AIController is EnemyAIController enemyAI && enemyAI.SelectedAiTarget?.Entity is Character && (enemyAI.State == AIState.Aggressive || enemyAI.State == AIState.Attack);
private bool IsBeingChased => SelectedAiTarget?.Entity is Character targetCharacter && IsBeingChasedBy(targetCharacter);

View File

@@ -771,17 +771,11 @@ namespace Barotrauma
targetHull = hull;
}
}
foreach (var ballastFlora in MapCreatures.Behavior.BallastFloraBehavior.EntityList)
if (IsBallastFloraNoticeable(Character, hull))
{
if (ballastFlora.Parent?.Submarine != Character.Submarine) { continue; }
if (!ballastFlora.HasBrokenThrough) { continue; }
// Don't react to the first two branches, because they are usually in the very edges of the room.
if (ballastFlora.Branches.Count(b => !b.Removed && b.Health > 0 && b.CurrentHull == hull) > 2)
{
var orderPrefab = Order.GetPrefab("reportballastflora");
newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
targetHull = hull;
}
var orderPrefab = Order.GetPrefab("reportballastflora");
newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
targetHull = hull;
}
if (!isFighting)
{
@@ -848,6 +842,21 @@ namespace Barotrauma
}
}
public static bool IsBallastFloraNoticeable(Character character, Hull hull)
{
foreach (var ballastFlora in MapCreatures.Behavior.BallastFloraBehavior.EntityList)
{
if (ballastFlora.Parent?.Submarine != character.Submarine) { continue; }
if (!ballastFlora.HasBrokenThrough) { continue; }
// Don't react to the first two branches, because they are usually in the very edges of the room.
if (ballastFlora.Branches.Count(b => !b.Removed && b.Health > 0 && b.CurrentHull == hull) > 2)
{
return true;
}
}
return false;
}
public static void ReportProblem(Character reporter, Order order)
{
if (reporter == null || order == null) { return; }

View File

@@ -58,16 +58,10 @@ namespace Barotrauma
}
else
{
if (!EjectEmptyTanks(character, targetItem, out var containedItems))
{
#if DEBUG
DebugConsole.ThrowError($"{character.Name}: AIObjectiveFindDivingGear failed - the item \"" + targetItem + "\" has no proper inventory");
#endif
Abandon = true;
return;
}
HumanAIController.UnequipContainedItems(targetItem, it => !it.HasTag("oxygensource"));
HumanAIController.UnequipEmptyItems(targetItem);
float min = character.Submarine == null ? 0.01f : MIN_OXYGEN;
if (containedItems.None(it => it != null && it.HasTag(OXYGEN_SOURCE) && it.Condition > min))
if (targetItem.OwnInventory != null && targetItem.OwnInventory.AllItems.None(it => it != null && it.HasTag(OXYGEN_SOURCE) && it.Condition > min))
{
// No valid oxygen source loaded.
// Seek oxygen that has at least 10% condition left.

View File

@@ -86,10 +86,9 @@ namespace Barotrauma
Abandon = true;
return;
}
// Drop empty tanks
HumanAIController.UnequipContainedItems(weldingTool, it => !it.HasTag("weldingfuel"));
HumanAIController.UnequipEmptyItems(weldingTool);
if (weldingTool.OwnInventory.AllItems.None(i => i.HasTag("weldingfuel") && i.Condition > 0.0f))
if (weldingTool.OwnInventory != null && weldingTool.OwnInventory.AllItems.None(i => i.HasTag("weldingfuel") && i.Condition > 0.0f))
{
TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, "weldingfuel", weldingTool.GetComponent<ItemContainer>(), objectiveManager, spawnItemIfNotFound: character.TeamID == CharacterTeamType.FriendlyNPC),
onAbandon: () =>

View File

@@ -122,7 +122,7 @@ namespace Barotrauma
Abandon = true;
return;
}
// Eject empty tanks
HumanAIController.UnequipContainedItems(repairTool.Item, it => !it.HasTag("weldingfuel"));
HumanAIController.UnequipEmptyItems(repairTool.Item);
RelatedItem item = null;
Item fuel = null;

View File

@@ -153,6 +153,8 @@ namespace Barotrauma
if (item.IsFullCondition) { return false; }
if (item.CurrentHull == null) { return false; }
if (item.Submarine == null || character.Submarine == null) { return false; }
//player crew ignores items in outposts
if (character.IsOnPlayerTeam && item.Submarine.Info.IsOutpost) { return false; }
if (!character.Submarine.IsEntityFoundOnThisSub(item, includingConnectedSubs: true)) { return false; }
if (item.Repairables.None()) { return false; }
return true;

View File

@@ -78,14 +78,14 @@ namespace Barotrauma
// Check if the character needs more oxygen
if (!ignoreOxygen && character.SelectedCharacter == targetCharacter || character.CanInteractWith(targetCharacter))
{
// Replace empty oxygen tank
// First remove empty tanks
// Replace empty oxygen and welding fuel.
if (HumanAIController.HasItem(targetCharacter, AIObjectiveFindDivingGear.HEAVY_DIVING_GEAR, out IEnumerable<Item> suits, requireEquipped: true))
{
Item suit = suits.FirstOrDefault();
if (suit != null)
{
AIObjectiveFindDivingGear.EjectEmptyTanks(character, suit, out _);
AIController.UnequipEmptyItems(character, suit);
AIController.UnequipContainedItems(character, suit, it => it.HasTag("weldingfuel"));
}
}
else if (HumanAIController.HasItem(targetCharacter, AIObjectiveFindDivingGear.LIGHT_DIVING_GEAR, out IEnumerable<Item> masks, requireEquipped: true))
@@ -93,7 +93,8 @@ namespace Barotrauma
Item mask = masks.FirstOrDefault();
if (mask != null)
{
AIObjectiveFindDivingGear.EjectEmptyTanks(character, mask, out _);
AIController.UnequipEmptyItems(character, mask);
AIController.UnequipContainedItems(character, mask, it => it.HasTag("weldingfuel"));
}
}
bool ShouldRemoveDivingSuit() => targetCharacter.OxygenAvailable < CharacterHealth.InsufficientOxygenThreshold && targetCharacter.CurrentHull?.LethalPressure <= 0;

View File

@@ -35,7 +35,7 @@ namespace Barotrauma
WayPointID = Waypoint.ID;
}
public static List<PathNode> GenerateNodes(List<WayPoint> wayPoints)
public static List<PathNode> GenerateNodes(List<WayPoint> wayPoints, bool removeOrphans)
{
var nodes = new Dictionary<int, PathNode>();
foreach (WayPoint wayPoint in wayPoints)
@@ -63,7 +63,10 @@ namespace Barotrauma
}
var nodeList = nodes.Values.ToList();
nodeList.RemoveAll(n => n.connections.Count == 0);
if (removeOrphans)
{
nodeList.RemoveAll(n => n.connections.Count == 0);
}
foreach (PathNode node in nodeList)
{
node.distances = new List<float>();
@@ -90,7 +93,7 @@ namespace Barotrauma
public PathFinder(List<WayPoint> wayPoints, bool indoorsSteering = false)
{
nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => w.Submarine != null == indoorsSteering));
nodes = PathNode.GenerateNodes(wayPoints.FindAll(w => w.Submarine != null == indoorsSteering), removeOrphans: true);
foreach (WayPoint wp in wayPoints)
{

View File

@@ -69,8 +69,8 @@ namespace Barotrauma
/// </summary>
public bool IsRemotelyControlled
{
get
{
get
{
if (GameMain.NetworkMember == null)
{
return false;
@@ -145,14 +145,8 @@ namespace Barotrauma
}
private readonly List<Attacker> lastAttackers = new List<Attacker>();
public IEnumerable<Attacker> LastAttackers
{
get { return lastAttackers; }
}
public Character LastAttacker
{
get { return lastAttackers.Count > 0 ? lastAttackers[lastAttackers.Count - 1].Character : null; }
}
public IEnumerable<Attacker> LastAttackers => lastAttackers;
public Character LastAttacker => lastAttackers.LastOrDefault()?.Character;
public Entity LastDamageSource;
@@ -203,7 +197,7 @@ namespace Barotrauma
public bool IsTraitor
{
get;
get;
set;
}
@@ -442,7 +436,7 @@ namespace Barotrauma
/// </summary>
public IEnumerable<Item> HeldItems
{
get
get
{
var item1 = Inventory?.GetItemInLimbSlot(InvSlotType.RightHand);
var item2 = Inventory?.GetItemInLimbSlot(InvSlotType.LeftHand);
@@ -527,7 +521,7 @@ namespace Barotrauma
}
public bool UseHullOxygen { get; set; } = true;
public float Stun
{
get { return IsRagdolled ? 1.0f : CharacterHealth.Stun; }
@@ -601,7 +595,7 @@ namespace Barotrauma
{
get;
set;
}
}
/// <summary>
/// Current speed of the character's collider. Can be used by status effects to check if the character is moving.
@@ -655,11 +649,11 @@ namespace Barotrauma
}
private bool isDead;
public bool IsDead
{
public bool IsDead
{
get { return isDead; }
set
{
set
{
if (isDead == value) { return; }
if (value)
{
@@ -822,7 +816,7 @@ namespace Barotrauma
speciesName = Path.GetFileNameWithoutExtension(speciesName).ToLowerInvariant();
}
var prefab = CharacterPrefab.FindBySpeciesName(speciesName);
var prefab = CharacterPrefab.FindBySpeciesName(speciesName);
if (prefab == null)
{
DebugConsole.ThrowError($"Failed to create character \"{speciesName}\". Matching prefab not found.\n" + Environment.StackTrace);
@@ -2191,8 +2185,7 @@ namespace Barotrauma
#if CLIENT
if (isLocalPlayer)
{
if (GUI.MouseOn == null &&
(!CharacterInventory.IsMouseOnInventory() || CharacterInventory.DraggingItemToWorld))
if (!IsMouseOnUI)
{
if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen)
{
@@ -2910,7 +2903,7 @@ namespace Barotrauma
}
}
// Prevent adding duplicate orders (same identifier and same option)
// Prevent adding duplicate orders
RemoveDuplicateOrders(order, orderOption);
OrderInfo newOrderInfo = new OrderInfo(order, orderOption, priority);
@@ -2971,7 +2964,7 @@ namespace Barotrauma
for (int i = CurrentOrders.Count - 1; i >= 0; i--)
{
var orderInfo = CurrentOrders[i];
if (orderInfo.MatchesOrder(order, option))
if (order?.Identifier == orderInfo.Order?.Identifier)
{
priorityOfRemoved = orderInfo.ManualPriority;
CurrentOrders.RemoveAt(i);
@@ -3316,6 +3309,13 @@ namespace Barotrauma
if (attacker.TeamID == TeamID) { return new AttackResult(); }
}
#if CLIENT
if (attacker == Controlled && Controlled != null && Params.UseBossHealthBar)
{
CharacterHUD.ShowBossHealthBar(this);
}
#endif
Vector2 dir = hitLimb.WorldPosition - worldPosition;
if (Math.Abs(attackImpulse) > 0.0f)
{
@@ -3351,14 +3351,14 @@ namespace Barotrauma
if (attackResult.Damage > 0)
{
LastDamage = attackResult;
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
if (attacker != null)
{
AddAttacker(attacker, attackResult.Damage);
AddEncounter(attacker);
attacker.AddEncounter(this);
}
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
}
return attackResult;
}
@@ -3418,6 +3418,16 @@ namespace Barotrauma
foreach (StatusEffect statusEffect in statusEffects)
{
if (statusEffect.type != actionType) { continue; }
if (statusEffect.type == ActionType.OnDamaged)
{
if (statusEffect.OnlyPlayerTriggered)
{
if (LastAttacker == null || !LastAttacker.IsPlayer)
{
continue;
}
}
}
if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
{

View File

@@ -148,10 +148,9 @@ namespace Barotrauma
}
}
public void Remove()
public void UnsubscribeFromDeathEvent()
{
if (character == null) { return; }
DeactivateHusk();
if (character == null || !subscribedToDeathEvent) { return; }
character.OnDeath -= CharacterDead;
subscribedToDeathEvent = false;
}
@@ -159,7 +158,11 @@ namespace Barotrauma
private void CharacterDead(Character character, CauseOfDeath causeOfDeath)
{
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
if (Strength < ActiveThreshold || character.Removed) { return; }
if (Strength < ActiveThreshold || character.Removed)
{
UnsubscribeFromDeathEvent();
return;
}
//don't turn the character into a husk if any of its limbs are severed
if (character.AnimController?.LimbJoints != null)
@@ -185,6 +188,7 @@ namespace Barotrauma
character.Enabled = false;
Entity.Spawner.AddToRemoveQueue(character);
UnsubscribeFromDeathEvent();
string huskedSpeciesName = GetHuskedSpeciesName(character.SpeciesName, Prefab as AfflictionPrefabHusk);
CharacterPrefab prefab = CharacterPrefab.FindBySpeciesName(huskedSpeciesName);

View File

@@ -613,9 +613,6 @@ namespace Barotrauma
case "icon":
Icon = new Sprite(subElement);
break;
case "periodiceffect":
periodicEffects.Add(new PeriodicEffect(subElement, Name));
break;
}
}
@@ -649,6 +646,9 @@ namespace Barotrauma
case "effect":
effects.Add(new Effect(subElement, Name));
break;
case "periodiceffect":
periodicEffects.Add(new PeriodicEffect(subElement, Name));
break;
}
}
}

View File

@@ -1125,6 +1125,16 @@ namespace Barotrauma
foreach (StatusEffect statusEffect in statusEffects)
{
if (statusEffect.type != actionType) { continue; }
if (statusEffect.type == ActionType.OnDamaged)
{
if (statusEffect.OnlyPlayerTriggered)
{
if (character.LastAttacker == null || !character.LastAttacker.IsPlayer)
{
continue;
}
}
}
if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
{

View File

@@ -49,6 +49,9 @@ namespace Barotrauma
[Serialize(false, false), Editable]
public bool CanSpeak { get; set; }
[Serialize(false, true), Editable]
public bool UseBossHealthBar { get; private set; }
[Serialize(100f, true, description: "How much noise the character makes when moving?"), Editable(minValue: 0f, maxValue: 100000f)]
public float Noise { get; set; }

View File

@@ -110,13 +110,14 @@ namespace Barotrauma
public Decal CreateDecal(string decalName, float scale, Vector2 worldPosition, Hull hull, int? spriteIndex = null)
{
if (!Prefabs.ContainsKey(decalName.ToLowerInvariant()))
string lowerCaseDecalName = decalName.ToLowerInvariant();
if (!Prefabs.ContainsKey(lowerCaseDecalName))
{
DebugConsole.ThrowError("Decal prefab " + decalName + " not found!");
return null;
}
DecalPrefab prefab = Prefabs[decalName];
DecalPrefab prefab = Prefabs[lowerCaseDecalName];
return new Decal(prefab, scale, worldPosition, hull, spriteIndex);
}

View File

@@ -66,5 +66,10 @@ namespace Barotrauma
return (Event)instance;
}
public override string ToString()
{
return $"EventPrefab ({Identifier})";
}
}
}

View File

@@ -299,6 +299,13 @@ namespace Barotrauma
System.Diagnostics.Debug.Assert(spawnPoint.ParentRuin == chosenPosition.Ruin);
spawnPos = spawnPoint.WorldPosition;
}
else
{
//no suitable position found, disable the event
spawnPos = null;
Finished();
return;
}
}
else if ((chosenPosition.PositionType == Level.PositionType.MainPath || chosenPosition.PositionType == Level.PositionType.SidePath)
&& offset > 0)

View File

@@ -22,7 +22,7 @@ namespace Barotrauma
public override string ToString()
{
return "ScriptedEvent (" + prefab.EventType.ToString() +")";
return $"ScriptedEvent ({prefab.Identifier})";
}
public ScriptedEvent(EventPrefab prefab) : base(prefab)

View File

@@ -71,10 +71,13 @@ namespace Barotrauma
else if (!isUnignoreOrder)
{
ActiveOrders.Add(new Pair<Order, float?>(order, fadeOutTime));
#if CLIENT
HintManager.OnActiveOrderAdded(order);
#endif
return true;
}
bool MatchesTarget(Entity existingTarget, Entity newTarget)
static bool MatchesTarget(Entity existingTarget, Entity newTarget)
{
if (existingTarget == newTarget) { return true; }
if (existingTarget is Hull existingHullTarget && newTarget is Hull newHullTarget)

View File

@@ -148,28 +148,26 @@ namespace Barotrauma
/// The location that's displayed as the "current one" in the map screen. Normally the current outpost or the location at the start of the level,
/// but when selecting the next destination at the end of the level at an uninhabited location we use the location at the end
/// </summary>
public Location CurrentDisplayLocation
public Location GetCurrentDisplayLocation()
{
get
if (Level.Loaded?.EndLocation != null && !Level.Loaded.Generating &&
Level.Loaded.Type == LevelData.LevelType.LocationConnection &&
GetAvailableTransition(out _, out _) == TransitionType.ProgressToNextEmptyLocation)
{
if (Level.Loaded?.EndLocation != null && !Level.Loaded.Generating &&
Level.Loaded.Type == LevelData.LevelType.LocationConnection &&
GetAvailableTransition(out _, out _) == TransitionType.ProgressToNextEmptyLocation)
{
return Level.Loaded.EndLocation;
}
return Level.Loaded?.StartLocation ?? Map.CurrentLocation;
return Level.Loaded.EndLocation;
}
return Level.Loaded?.StartLocation ?? Map.CurrentLocation;
}
public List<Submarine> GetSubsToLeaveBehind(Submarine leavingSub)
{
//leave subs behind if they're not docked to the leaving sub and not at the same exit
return Submarine.Loaded.FindAll(s =>
s != leavingSub &&
!leavingSub.DockedTo.Contains(s) &&
s.Info.Type == SubmarineType.Player &&
(s.AtEndExit != leavingSub.AtEndExit || s.AtStartExit != leavingSub.AtStartExit));
return Submarine.Loaded.FindAll(sub =>
sub != leavingSub &&
!leavingSub.DockedTo.Contains(sub) &&
sub.Info.Type == SubmarineType.Player &&
sub != GameMain.NetworkMember?.RespawnManager?.RespawnShuttle &&
(sub.AtEndExit != leavingSub.AtEndExit || sub.AtStartExit != leavingSub.AtStartExit));
}
public override void Start()
@@ -476,7 +474,7 @@ namespace Barotrauma
{
if (Level.Loaded.StartOutpost == null)
{
Submarine closestSub = Submarine.FindClosest(Level.Loaded.StartExitPosition, ignoreOutposts: true);
Submarine closestSub = Submarine.FindClosest(Level.Loaded.StartExitPosition, ignoreOutposts: true, ignoreRespawnShuttle: true);
return closestSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : closestSub;
}
else
@@ -490,7 +488,7 @@ namespace Barotrauma
//nothing docked, check if there's a sub close enough to the outpost and someone inside the outpost
if (Level.Loaded.Type == LevelData.LevelType.LocationConnection && !leavingPlayers.Any(s => s.Submarine == Level.Loaded.StartOutpost)) { return null; }
Submarine closestSub = Submarine.FindClosest(Level.Loaded.StartOutpost.WorldPosition, ignoreOutposts: true);
Submarine closestSub = Submarine.FindClosest(Level.Loaded.StartOutpost.WorldPosition, ignoreOutposts: true, ignoreRespawnShuttle: true);
if (closestSub == null || !closestSub.AtStartExit) { return null; }
return closestSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : closestSub;
}
@@ -503,7 +501,7 @@ namespace Barotrauma
if (Level.Loaded.EndOutpost == null)
{
Submarine closestSub = Submarine.FindClosest(Level.Loaded.EndPosition, ignoreOutposts: true);
Submarine closestSub = Submarine.FindClosest(Level.Loaded.EndPosition, ignoreOutposts: true, ignoreRespawnShuttle: true);
return closestSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : closestSub;
}
else
@@ -517,7 +515,7 @@ namespace Barotrauma
//nothing docked, check if there's a sub close enough to the outpost and someone inside the outpost
if (Level.Loaded.Type == LevelData.LevelType.LocationConnection && !leavingPlayers.Any(s => s.Submarine == Level.Loaded.EndOutpost)) { return null; }
Submarine closestSub = Submarine.FindClosest(Level.Loaded.EndOutpost.WorldPosition, ignoreOutposts: true);
Submarine closestSub = Submarine.FindClosest(Level.Loaded.EndOutpost.WorldPosition, ignoreOutposts: true, ignoreRespawnShuttle: true);
if (closestSub == null || !closestSub.AtEndExit) { return null; }
return closestSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : closestSub;
}
@@ -625,7 +623,10 @@ namespace Barotrauma
}
Map.SetLocation(Map.Locations.IndexOf(Map.StartLocation));
Map.SelectLocation(-1);
Map.Radiation.Amount = Map.Radiation.Params.StartingRadiation;
if (Map.Radiation != null)
{
Map.Radiation.Amount = Map.Radiation.Params.StartingRadiation;
}
foreach (Location location in Map.Locations)
{
location.TurnsInRadiation = 0;

View File

@@ -875,6 +875,7 @@ namespace Barotrauma.Items.Components
Item.Submarine.EnableObstructedWaypoints(DockingTarget.Item.Submarine);
obstructedWayPointsDisabled = false;
Item.Submarine.RefreshOutdoorNodes();
DockingTarget.Undock();
DockingTarget = null;
@@ -1000,6 +1001,7 @@ namespace Barotrauma.Items.Components
if (!obstructedWayPointsDisabled && dockingState >= 0.99f)
{
Item.Submarine.DisableObstructedWayPoints(DockingTarget?.Item.Submarine);
Item.Submarine.RefreshOutdoorNodes();
obstructedWayPointsDisabled = true;
}
}

View File

@@ -31,7 +31,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
@@ -46,7 +46,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength)
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}

View File

@@ -1,5 +1,4 @@
using Microsoft.Xna.Framework;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
@@ -11,7 +10,10 @@ namespace Barotrauma.Items.Components
//how many wires can be linked to connectors by default
private const int DefaultMaxWires = 5;
//how many wires can be linked to this connection
//how many wires a player can link to this connection
public readonly int MaxPlayerConnectableWires = 5;
//how many wires can be linked to this connection in total
public readonly int MaxWires = 5;
public readonly string Name;
@@ -81,6 +83,7 @@ namespace Barotrauma.Items.Components
item = connectionPanel.Item;
MaxWires = element.GetAttributeInt("maxwires", DefaultMaxWires);
MaxPlayerConnectableWires = element.GetAttributeInt("maxplayerconnectablewires", MaxWires);
wires = new Wire[MaxWires];
IsOutput = element.Name.ToString() == "output";

View File

@@ -16,13 +16,18 @@ namespace Barotrauma.Items.Components
[Serialize("", false, translationTextTag: "Label.", description: "The text displayed on this button/tickbox."), Editable]
public string Label { get; set; }
[Serialize("1", false, description: "The signal sent out when this button is pressed or this tickbox checked."), Editable]
public string Signal { get; set; }
public string PropertyName { get; }
public bool TargetOnlyParentProperty { get; }
public int NumberInputMin { get; }
public int NumberInputMax { get; }
public int MaxTextLength { get; }
public const int DefaultNumberInputMin = 0, DefaultNumberInputMax = 99;
public bool IsIntegerInput { get; }
public bool HasPropertyName { get; }
@@ -46,7 +51,7 @@ namespace Barotrauma.Items.Components
TargetOnlyParentProperty = element.GetAttributeBool("targetonlyparentproperty", false);
NumberInputMin = element.GetAttributeInt("min", DefaultNumberInputMin);
NumberInputMax = element.GetAttributeInt("max", DefaultNumberInputMax);
MaxTextLength = element.GetAttributeInt("maxtextlength", int.MaxValue);
HasPropertyName = !string.IsNullOrEmpty(PropertyName);
IsIntegerInput = HasPropertyName && element.Name.ToString().ToLowerInvariant() == "integerinput";

View File

@@ -23,7 +23,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
@@ -38,7 +38,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength)
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}

View File

@@ -83,7 +83,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
@@ -99,7 +99,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength)
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}

View File

@@ -28,7 +28,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}

View File

@@ -14,7 +14,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
@@ -30,7 +30,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength)
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}

View File

@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
@@ -35,7 +35,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength)
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}

View File

@@ -21,7 +21,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
output = value;
if (output.Length > MaxOutputLength)
if (output.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
output = output.Substring(0, MaxOutputLength);
}
@@ -37,7 +37,7 @@ namespace Barotrauma.Items.Components
{
if (value == null) { return; }
falseOutput = value;
if (falseOutput.Length > MaxOutputLength)
if (falseOutput.Length > MaxOutputLength && (item.Submarine == null || !item.Submarine.Loading))
{
falseOutput = falseOutput.Substring(0, MaxOutputLength);
}

View File

@@ -348,7 +348,7 @@ namespace Barotrauma
{
if (AiTarget != null)
{
AiTarget.SonarLabel = value;
AiTarget.SonarLabel = !string.IsNullOrEmpty(value) && value.Length > 200 ? value.Substring(200) : value;
}
}
}

View File

@@ -111,7 +111,7 @@ namespace Barotrauma
public override bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true)
{
bool wasPut = base.TryPutItem(item, i, allowSwapping, allowCombine, user, createNetworkEvent);
if (wasPut)
if (wasPut && item.ParentInventory == this)
{
foreach (Character c in Character.CharacterList)
{

View File

@@ -524,6 +524,11 @@ namespace Barotrauma
public bool CanBeBought => (DefaultPrice != null && DefaultPrice.CanBeBought) || (locationPrices != null && locationPrices.Any(p => p.Value.CanBeBought));
/// <summary>
/// Can the item be chosen as extra cargo in multiplayer. If not set, the item is available if it can be bought from outposts in the campaign.
/// </summary>
public bool? AllowAsExtraCargo;
/// <summary>
/// Any item with a Price element in the definition can be sold everywhere.
/// </summary>
@@ -719,6 +724,11 @@ namespace Barotrauma
FabricationRecipes = new List<FabricationRecipe>();
DeconstructTime = 1.0f;
if (element.Attribute("allowasextracargo") != null)
{
AllowAsExtraCargo = element.GetAttributeBool("allowasextracargo", false);
}
Tags = new HashSet<string>(element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true));
if (!Tags.Any())
{

View File

@@ -142,7 +142,7 @@ namespace Barotrauma
if (displayRange < 0.1f) { return; }
if (Attack.GetStructureDamage(1.0f) > 0.0f)
if (Attack.GetStructureDamage(1.0f) > 0.0f || Attack.GetLevelWallDamage(1.0f) > 0.0f)
{
RangedStructureDamage(worldPosition, displayRange, Attack.GetStructureDamage(1.0f), Attack.GetLevelWallDamage(1.0f), attacker);
}

View File

@@ -3603,31 +3603,36 @@ namespace Barotrauma
}
//remove wires
foreach (Item item in beaconItems.Where(it => it.GetComponent<Wire>() != null).ToList())
float removeWireMinDifficulty = 20.0f;
float removeWireProbability = MathUtils.InverseLerp(removeWireMinDifficulty, 100.0f, LevelData.Difficulty) * 0.5f;
if (removeWireProbability > 0.0f)
{
if (item.NonInteractable) { continue; }
Wire wire = item.GetComponent<Wire>();
if (wire.Locked) { continue; }
if (wire.Connections[0] != null && (wire.Connections[0].Item.NonInteractable || wire.Connections[0].Item.GetComponent<ConnectionPanel>().Locked))
foreach (Item item in beaconItems.Where(it => it.GetComponent<Wire>() != null).ToList())
{
continue;
}
if (wire.Connections[1] != null && (wire.Connections[1].Item.NonInteractable || wire.Connections[1].Item.GetComponent<ConnectionPanel>().Locked))
{
continue;
}
if (Rand.Range(0f, 1f, Rand.RandSync.Unsynced) < 0.25f)
{
foreach (Connection connection in wire.Connections)
if (item.NonInteractable) { continue; }
Wire wire = item.GetComponent<Wire>();
if (wire.Locked) { continue; }
if (wire.Connections[0] != null && (wire.Connections[0].Item.NonInteractable || wire.Connections[0].Item.GetComponent<ConnectionPanel>().Locked))
{
if (connection != null)
continue;
}
if (wire.Connections[1] != null && (wire.Connections[1].Item.NonInteractable || wire.Connections[1].Item.GetComponent<ConnectionPanel>().Locked))
{
continue;
}
if (Rand.Range(0f, 1.0f, Rand.RandSync.Unsynced) < removeWireProbability)
{
foreach (Connection connection in wire.Connections)
{
connection.ConnectionPanel.DisconnectedWires.Add(wire);
wire.RemoveConnection(connection.Item);
if (connection != null)
{
connection.ConnectionPanel.DisconnectedWires.Add(wire);
wire.RemoveConnection(connection.Item);
#if SERVER
connection.ConnectionPanel.Item.CreateServerEvent(connection.ConnectionPanel);
wire.CreateNetworkEvent();
#endif
}
}
}
}

View File

@@ -117,8 +117,7 @@ namespace Barotrauma
EventHistory.AddRange(EventSet.PrefabList.Where(p => prefabNames.Any(n => p.Identifier.Equals(n, StringComparison.InvariantCultureIgnoreCase))));
string[] nonRepeatablePrefabNames = element.GetAttributeStringArray("nonrepeatableevents", new string[] { });
NonRepeatableEvents.AddRange(EventSet.PrefabList.Where(p => prefabNames.Any(n => p.Identifier.Equals(n, StringComparison.InvariantCultureIgnoreCase))));
NonRepeatableEvents.AddRange(EventSet.PrefabList.Where(p => nonRepeatablePrefabNames.Any(n => p.Identifier.Equals(n, StringComparison.InvariantCultureIgnoreCase))));
}

View File

@@ -183,10 +183,10 @@ namespace Barotrauma
else
{
string levelSeed = element.GetAttributeString("location", "");
LevelData levelData = GameMain.GameSession.Campaign?.NextLevel ?? GameMain.GameSession.LevelData;
LevelData levelData = GameMain.GameSession?.Campaign?.NextLevel ?? GameMain.GameSession?.LevelData;
linkedSub = new LinkedSubmarine(submarine, idRemap.AssignMaxId())
{
purchasedLostShuttles = GameMain.GameSession.GameMode is CampaignMode campaign && campaign.PurchasedLostShuttles,
purchasedLostShuttles = GameMain.GameSession?.GameMode is CampaignMode campaign && campaign.PurchasedLostShuttles,
saveElement = element
};

View File

@@ -591,9 +591,9 @@ namespace Barotrauma
public bool IsCriticallyRadiated()
{
if (GameMain.GameSession is { Campaign: { Map: { } map } })
if (GameMain.GameSession?.Map?.Radiation != null)
{
return TurnsInRadiation > map.Radiation.Params.CriticalRadiationThreshold;
return TurnsInRadiation > GameMain.GameSession.Map.Radiation.Params.CriticalRadiationThreshold;
}
return false;
@@ -708,7 +708,7 @@ namespace Barotrauma
}
}
public bool IsRadiated() => GameMain.GameSession is { Campaign: { Map: { Radiation: { Enabled: true } radiation } } } && radiation.Contains(this);
public bool IsRadiated() => GameMain.GameSession?.Map?.Radiation != null && GameMain.GameSession.Map.Radiation.Enabled && GameMain.GameSession.Map.Radiation.Contains(this);
private List<PurchasedItem> CreateStoreStock()
{

View File

@@ -16,8 +16,8 @@ namespace Barotrauma
private Location furthestDiscoveredLocation;
public int Width => generationParams.Width;
public int Height => generationParams.Height;
public int Width { get; private set; }
public int Height { get; private set; }
public Action<Location, LocationConnection> OnLocationSelected;
/// <summary>
@@ -62,12 +62,17 @@ namespace Barotrauma
public Map(CampaignSettings settings)
{
generationParams = MapGenerationParams.Instance;
Width = generationParams.Width;
Height = generationParams.Height;
Locations = new List<Location>();
Connections = new List<LocationConnection>();
Radiation = new Radiation(this, generationParams.RadiationParams)
if (generationParams.RadiationParams != null)
{
Enabled = settings.RadiationEnabled
};
Radiation = new Radiation(this, generationParams.RadiationParams)
{
Enabled = settings.RadiationEnabled
};
}
}
/// <summary>
@@ -78,6 +83,9 @@ namespace Barotrauma
Seed = element.GetAttributeString("seed", "a");
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed));
Width = element.GetAttributeInt("width", Width);
Height = element.GetAttributeInt("height", Height);
bool lairsFound = false;
foreach (XElement subElement in element.Elements())
@@ -180,6 +188,12 @@ namespace Barotrauma
}
}
//backwards compatibility: if locations go out of bounds (map saved with different generation parameters before width/height were included in the xml)
float maxX = Locations.Select(l => l.MapPosition.X).Max();
if (maxX > Width) { Width = (int)(maxX + 10); }
float maxY = Locations.Select(l => l.MapPosition.Y).Max();
if (maxY > Height) { Height = (int)(maxY + 10); }
InitProjectSpecific();
}
@@ -405,6 +419,7 @@ namespace Barotrauma
int zone1 = GetZoneIndex(Connections[i].Locations[0].MapPosition.X);
int zone2 = GetZoneIndex(Connections[i].Locations[1].MapPosition.X);
if (zone1 == zone2) { continue; }
if (zone2 == generationParams.DifficultyZones) { continue; }
if (!connectionsBetweenZones.Contains(Connections[i]))
{
@@ -416,9 +431,9 @@ namespace Barotrauma
Connections[i].Locations[0].MapPosition.X < Connections[i].Locations[1].MapPosition.X ?
Connections[i].Locations[0] :
Connections[i].Locations[1];
if (!leftMostLocation.Type.HasOutpost)
if (!leftMostLocation.Type.HasOutpost || leftMostLocation.Type.Identifier.Equals("abandoned", StringComparison.OrdinalIgnoreCase))
{
leftMostLocation.ChangeType(LocationType.List.First(lt => lt.HasOutpost));
leftMostLocation.ChangeType(LocationType.List.First(lt => lt.HasOutpost && !lt.Identifier.Equals("abandoned", StringComparison.OrdinalIgnoreCase)));
}
leftMostLocation.IsGateBetweenBiomes = true;
Connections[i].Locked = true;
@@ -708,8 +723,9 @@ namespace Barotrauma
}
SelectedLocation = Locations[index];
var currentDisplayLocation = GameMain.GameSession?.Campaign?.GetCurrentDisplayLocation();
SelectedConnection =
Connections.Find(c => c.Locations.Contains(GameMain.GameSession?.Campaign?.CurrentDisplayLocation) && c.Locations.Contains(SelectedLocation)) ??
Connections.Find(c => c.Locations.Contains(currentDisplayLocation) && c.Locations.Contains(SelectedLocation)) ??
Connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
if (SelectedConnection?.Locked ?? false)
{
@@ -796,7 +812,7 @@ namespace Barotrauma
ProgressWorld();
}
Radiation.OnStep(steps);
Radiation?.OnStep(steps);
}
private void ProgressWorld()
@@ -1092,6 +1108,8 @@ namespace Barotrauma
mapElement.Add(new XAttribute("currentlocationconnection", Connections.IndexOf(Connections.Find(c => c.LevelData == Level.Loaded.LevelData))));
}
}
mapElement.Add(new XAttribute("width", Width));
mapElement.Add(new XAttribute("height", Height));
mapElement.Add(new XAttribute("selectedlocation", SelectedLocationIndex));
mapElement.Add(new XAttribute("startlocation", Locations.IndexOf(StartLocation)));
mapElement.Add(new XAttribute("endlocation", Locations.IndexOf(EndLocation)));
@@ -1118,7 +1136,10 @@ namespace Barotrauma
mapElement.Add(connectionElement);
}
mapElement.Add(Radiation.Save());
if (Radiation != null)
{
mapElement.Add(Radiation.Save());
}
element.Add(mapElement);
}

View File

@@ -133,7 +133,7 @@ namespace Barotrauma
public Rectangle Borders
{
get
get
{
return subBody == null ? Rectangle.Empty : subBody.Borders;
}
@@ -155,7 +155,7 @@ namespace Barotrauma
private float? realWorldCrushDepth;
public float RealWorldCrushDepth
{
get
get
{
if (!realWorldCrushDepth.HasValue)
{
@@ -172,6 +172,7 @@ namespace Barotrauma
}
return realWorldCrushDepth.Value;
}
set { realWorldCrushDepth = value; }
}
/// <summary>
@@ -179,7 +180,7 @@ namespace Barotrauma
/// </summary>
public float RealWorldDepth
{
get
get
{
if (Level.Loaded?.GenerationParams == null)
{
@@ -191,7 +192,7 @@ namespace Barotrauma
public bool AtEndExit
{
get
get
{
if (Level.Loaded == null) { return false; }
if (Level.Loaded.EndOutpost != null && DockedTo.Contains(Level.Loaded.EndOutpost))
@@ -247,7 +248,7 @@ namespace Barotrauma
public bool AtDamageDepth
{
get
get
{
if (Level.Loaded == null || subBody == null) { return false; }
return RealWorldDepth > Level.Loaded.RealWorldCrushDepth && RealWorldDepth > RealWorldCrushDepth;
@@ -330,7 +331,7 @@ namespace Barotrauma
foreach (Item item in Item.ItemList)
{
if (item.Submarine != this) { continue; }
if (item.prefab.Identifier == "idcardwreck" || item.prefab.Identifier == "idcard")
if (item.prefab.Identifier == "idcardwreck" || item.prefab.Identifier == "idcard")
{
foreach (string tag in item.GetTags().ToList())
{
@@ -338,7 +339,7 @@ namespace Barotrauma
string newTag = Level.Loaded.GetWreckIDTag(tag, this);
item.ReplaceTag(tag, newTag);
ReplaceIDCardTagRequirements(tag, newTag);
}
}
}
}
@@ -452,7 +453,7 @@ namespace Barotrauma
public Vector2 FindSpawnPos(Vector2 spawnPos, Point? submarineSize = null, float subDockingPortOffset = 0.0f, int verticalMoveDir = 0)
{
Rectangle dockedBorders = GetDockedBorders();
Vector2 diffFromDockedBorders =
Vector2 diffFromDockedBorders =
new Vector2(dockedBorders.Center.X, dockedBorders.Y - dockedBorders.Height / 2)
- new Vector2(Borders.Center.X, Borders.Y - Borders.Height / 2);
@@ -503,7 +504,7 @@ namespace Barotrauma
(e.Point1.Y > refPos.Y + minHeight * 0.5f && e.Point2.Y > refPos.Y + minHeight * 0.5f))
{
continue;
}
}
if (cell.Site.Coord.X < refPos.X)
{
@@ -550,7 +551,7 @@ namespace Barotrauma
//walls found at both sides, use their midpoint
spawnPos.X = (limits.X + limits.Y) / 2 + subDockingPortOffset;
}
spawnPos.Y = MathHelper.Clamp(spawnPos.Y, dockedBorders.Height / 2 + 10, Level.Loaded.Size.Y - dockedBorders.Height / 2 - padding * 2);
return spawnPos - diffFromDockedBorders;
}
@@ -617,7 +618,7 @@ namespace Barotrauma
return new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));
}
public static Rectangle AbsRect(Vector2 pos, Vector2 size)
{
if (size.X < 0.0f)
@@ -630,7 +631,7 @@ namespace Barotrauma
pos.Y -= size.Y;
size.Y = -size.Y;
}
return new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y);
}
@@ -684,7 +685,7 @@ namespace Barotrauma
closestFraction = 0.0f;
closestNormal = Vector2.Normalize(rayEnd - rayStart);
if (fixture.Body != null) closestBody = fixture.Body;
if (fixture.Body != null) closestBody = fixture.Body;
return false;
}, ref aabb);
if (closestFraction <= 0.0f)
@@ -695,7 +696,7 @@ namespace Barotrauma
return closestBody;
}
}
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return -1; }
@@ -712,7 +713,7 @@ namespace Barotrauma
lastPickedPosition = rayStart + (rayEnd - rayStart) * closestFraction;
lastPickedFraction = closestFraction;
lastPickedNormal = closestNormal;
return closestBody;
}
@@ -837,13 +838,13 @@ namespace Barotrauma
lastPickedPosition = rayEnd;
return null;
}
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
if (fixture == null) { return -1; }
if (ignoreSensors && fixture.IsSensor) { return -1; }
if (ignoreLevel && fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) { return -1; }
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)
&& !fixture.CollisionCategories.HasFlag(Physics.CollisionWall)
&& !fixture.CollisionCategories.HasFlag(Physics.CollisionRepair)) { return -1; }
if (ignoreSubs && fixture.Body.UserData is Submarine) { return -1; }
@@ -890,7 +891,7 @@ namespace Barotrauma
parents.Add(this);
flippedX = !flippedX;
Item.UpdateHulls();
List<Item> bodyItems = Item.ItemList.FindAll(it => it.Submarine == this && it.body != null);
@@ -1174,7 +1175,7 @@ namespace Barotrauma
subBody.SetPosition(subBody.Position + amount);
}
public static Submarine FindClosest(Vector2 worldPosition, bool ignoreOutposts = false, bool ignoreOutsideLevel = true)
public static Submarine FindClosest(Vector2 worldPosition, bool ignoreOutposts = false, bool ignoreOutsideLevel = true, bool ignoreRespawnShuttle = false)
{
Submarine closest = null;
float closestDist = 0.0f;
@@ -1182,6 +1183,10 @@ namespace Barotrauma
{
if (ignoreOutposts && sub.Info.IsOutpost) { continue; }
if (ignoreOutsideLevel && Level.Loaded != null && sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
if (ignoreRespawnShuttle)
{
if (sub == GameMain.NetworkMember?.RespawnManager?.RespawnShuttle) { continue; }
}
float dist = Vector2.DistanceSquared(worldPosition, sub.WorldPosition);
if (closest == null || dist < closestDist)
{
@@ -1344,9 +1349,9 @@ namespace Barotrauma
PhysicsBody.FarseerBody.BodyType = BodyType.Static;
TeamID = CharacterTeamType.FriendlyNPC;
bool indestructible =
GameMain.NetworkMember != null &&
!GameMain.NetworkMember.ServerSettings.DestructibleOutposts &&
bool indestructible =
GameMain.NetworkMember != null &&
!GameMain.NetworkMember.ServerSettings.DestructibleOutposts &&
!(info.OutpostGenerationParams?.AlwaysDestructible ?? false);
foreach (MapEntity me in MapEntity.mapEntityList)
@@ -1432,7 +1437,7 @@ namespace Barotrauma
//halve the brightness of the lights to make them look (almost) right on the new lighting formula
if (showWarningMessages &&
!string.IsNullOrEmpty(Info.FilePath) &&
Screen.Selected != GameMain.SubEditorScreen &&
Screen.Selected != GameMain.SubEditorScreen &&
(Info.GameVersion == null || Info.GameVersion < new Version("0.8.9.0")))
{
DebugConsole.ThrowError("The submarine \"" + Info.Name + "\" was made using an older version of the Barotrauma that used a different formula to calculate the lighting. "
@@ -1445,6 +1450,7 @@ namespace Barotrauma
if (lightComponent != null) lightComponent.LightColor = new Color(lightComponent.LightColor, lightComponent.LightColor.A / 255.0f * 0.5f);
}
}
GenerateOutdoorNodes();
}
protected override ushort DetermineID(ushort id, Submarine submarine)
@@ -1500,7 +1506,7 @@ namespace Barotrauma
element.Add(new XAttribute("recommendedcrewsizemax", Info.RecommendedCrewSizeMax));
element.Add(new XAttribute("recommendedcrewexperience", Info.RecommendedCrewExperience ?? ""));
element.Add(new XAttribute("requiredcontentpackages", string.Join(", ", Info.RequiredContentPackages)));
if (Info.Type == SubmarineType.OutpostModule)
{
Info.OutpostModuleInfo?.Save(element);
@@ -1606,7 +1612,7 @@ namespace Barotrauma
PhysicsBody.RemoveAll();
GameMain.World.Clear();
GameMain.World.Clear();
Unloading = false;
}
@@ -1651,12 +1657,18 @@ namespace Barotrauma
{
if (outdoorNodes == null)
{
outdoorNodes = PathNode.GenerateNodes(WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Path && wp.Submarine == this && wp.CurrentHull == null));
GenerateOutdoorNodes();
}
return outdoorNodes;
}
}
private void GenerateOutdoorNodes()
{
var waypoints = WayPoint.WayPointList.FindAll(wp => wp.SpawnType == SpawnType.Path && wp.Submarine == this && wp.CurrentHull == null);
outdoorNodes = PathNode.GenerateNodes(waypoints, removeOrphans: false);
}
private readonly Dictionary<Submarine, HashSet<PathNode>> obstructedNodes = new Dictionary<Submarine, HashSet<PathNode>>();
/// <summary>
@@ -1724,7 +1736,6 @@ namespace Barotrauma
}
}
}
node.Waypoint.FindHull();
}
}
@@ -1739,7 +1750,8 @@ namespace Barotrauma
nodes.Clear();
obstructedNodes.Remove(otherSub);
}
OutdoorNodes.ForEach(n => n.Waypoint.FindHull());
}
public void RefreshOutdoorNodes() => OutdoorNodes.ForEach(n => n?.Waypoint?.FindHull());
}
}

View File

@@ -453,7 +453,7 @@ namespace Barotrauma
//camera shake and sounds start playing 500 meters before crush depth
float depthEffectThreshold = 500.0f;
if (Submarine.RealWorldDepth < Level.Loaded.RealWorldCrushDepth - depthEffectThreshold && Submarine.RealWorldDepth < Submarine.RealWorldCrushDepth - depthEffectThreshold)
if (Submarine.RealWorldDepth < Level.Loaded.RealWorldCrushDepth - depthEffectThreshold || Submarine.RealWorldDepth < Submarine.RealWorldCrushDepth - depthEffectThreshold)
{
return;
}

View File

@@ -275,7 +275,7 @@ namespace Barotrauma
OutpostModuleInfo = new OutpostModuleInfo(original.OutpostModuleInfo);
}
#if CLIENT
PreviewImage = original.PreviewImage != null ? new Sprite(original.PreviewImage.Texture, null, null) : null;
PreviewImage = original.PreviewImage != null ? new Sprite(original.PreviewImage) : null;
#endif
}

View File

@@ -144,7 +144,7 @@ namespace Barotrauma
DebugConsole.Log("Created waypoint (" + ID + ")");
CurrentHull = Hull.FindHull(WorldPosition);
FindHull();
}
public override MapEntity Clone()
@@ -791,7 +791,7 @@ namespace Barotrauma
public override void OnMapLoaded()
{
InitializeLinks();
CurrentHull = Hull.FindHull(WorldPosition, CurrentHull);
FindHull();
FindStairs();
}

View File

@@ -82,7 +82,7 @@ namespace Barotrauma.Networking
{
get
{
return string.IsNullOrWhiteSpace(SenderName) ? TranslatedText : SenderName + ": " + TranslatedText;
return string.IsNullOrWhiteSpace(SenderName) ? TranslatedText : NetworkMember.ClientLogName(SenderClient, SenderName) + ": " + TranslatedText;
}
}

View File

@@ -237,9 +237,9 @@ namespace Barotrauma.Networking
return radioComponent.HasRequiredContainedItems(sender, addMessage: false);
}
public void AddChatMessage(string message, ChatMessageType type, string senderName = "", Character senderCharacter = null, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None)
public void AddChatMessage(string message, ChatMessageType type, string senderName = "", Client senderClient = null, Character senderCharacter = null, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None)
{
AddChatMessage(ChatMessage.Create(senderName, message, type, senderCharacter, changeType: changeType));
AddChatMessage(ChatMessage.Create(senderName, message, type, senderCharacter, senderClient, changeType: changeType));
}
public virtual void AddChatMessage(ChatMessage message)
@@ -252,6 +252,18 @@ namespace Barotrauma.Networking
}
}
public static string ClientLogName(Client client, string name = null)
{
if (client == null) { return name; }
string retVal = "‖";
if (client.Karma < 40.0f)
{
retVal += "color:#ff9900;";
}
retVal += "metadata:" + (client.SteamID != 0 ? client.SteamID.ToString() : client.ID.ToString()) + "‖" + (name ?? client.Name).Replace("‖", "") + "‖end‖";
return retVal;
}
public virtual void KickPlayer(string kickedName, string reason) { }
public virtual void BanPlayer(string kickedName, string reason, bool range = false, TimeSpan? duration = null) { }

View File

@@ -70,6 +70,8 @@ namespace Barotrauma.Networking
{
RespawnShuttle = new Submarine(shuttleInfo, true);
RespawnShuttle.PhysicsBody.FarseerBody.OnCollision += OnShuttleCollision;
//set crush depth slightly deeper than the main sub's
RespawnShuttle.RealWorldCrushDepth = Math.Max(RespawnShuttle.RealWorldCrushDepth, Submarine.MainSub.RealWorldCrushDepth * 1.2f);
//prevent wifi components from communicating between the respawn shuttle and other subs
List<WifiComponent> wifiComponents = new List<WifiComponent>();

View File

@@ -244,7 +244,7 @@ namespace Barotrauma
cam.TargetPos = targetPos;
}
cam.MoveCamera((float)deltaTime);
cam.MoveCamera((float)deltaTime, allowZoom: GUI.MouseOn == null);
#endif
foreach (Submarine sub in Submarine.Loaded)

View File

@@ -40,6 +40,7 @@ namespace Barotrauma
public void SetRadiationEnabled(bool enabled)
{
#if CLIENT
if (radiationEnabledTickBox == null) { return; }
radiationEnabledTickBox.Selected = enabled;
#endif
}
@@ -47,7 +48,7 @@ namespace Barotrauma
public bool IsRadiationEnabled()
{
#if CLIENT
return radiationEnabledTickBox.Selected;
return radiationEnabledTickBox != null && radiationEnabledTickBox.Selected;
#elif SERVER
return GameMain.Server.ServerSettings.RadiationEnabled;
#endif

Some files were not shown because too many files have changed in this diff Show More