Release 1.9.7.0 - Summer Update 2025

This commit is contained in:
Regalis11
2025-06-17 16:38:11 +03:00
parent 22227f13e5
commit ea5a2bc693
297 changed files with 7344 additions and 2421 deletions
@@ -771,6 +771,8 @@ namespace Barotrauma
private QuickUseAction GetQuickUseAction(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment)
{
if (!item.IsInteractable(Character.Controlled)) { return QuickUseAction.None; }
if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null &&
//if the item can be equipped in the health interface slot, don't use it as a treatment but try to equip it
!item.AllowedSlots.Contains(InvSlotType.HealthInterface))
@@ -158,7 +158,7 @@ namespace Barotrauma.Items.Components
public void ClientEventRead(IReadMessage msg, float sendingTime)
{
Health = msg.ReadRangedSingle(0, MaxHealth, 8);
Health = msg.ReadRangedSingle(0, MaxWater, 8);
int startOffset = msg.ReadRangedInteger(-1, MaximumVines);
if (startOffset > -1)
{
@@ -1,8 +1,9 @@
using Barotrauma.Networking;
using Barotrauma.Extensions;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Diagnostics.Tracing;
using System.Collections.Generic;
namespace Barotrauma.Items.Components
{
@@ -15,18 +16,33 @@ namespace Barotrauma.Items.Components
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1, Color? overrideColor = null)
{
if (!IsActive || picker == null || !CanBeAttached(picker) || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled)
if (!IsActive || picker == null || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled || !attachable)
{
Drawable = false;
return;
}
Vector2 gridPos = picker.Position;
Vector2 roundedGridPos = new Vector2(
MathUtils.RoundTowardsClosest(picker.Position.X, Submarine.GridSize.X),
MathUtils.RoundTowardsClosest(picker.Position.Y, Submarine.GridSize.Y));
Color indicatorColor = Color.White;
if (!CanBeAttached(picker, out IEnumerable<Item> overlappingItems))
{
foreach (var overlappingItem in overlappingItems)
{
overlappingItem.Draw(spriteBatch, editing: false, overrideColor: Color.Red * 0.7f, overrideDepth: 0.0f);
}
indicatorColor = Color.Red;
}
Vector2 attachPos = GetAttachPosition(picker);
Vector2 gridPos = picker.Position;
if (AttachesToFloor)
{
gridPos.Y = attachPos.Y - item.Rect.Height / 2;
}
Vector2 roundedGridPos = new Vector2(
MathUtils.RoundTowardsClosest(gridPos.X, Submarine.GridSize.X),
MathUtils.RoundTowardsClosest(gridPos.Y, Submarine.GridSize.Y));
if (item.Submarine == null)
{
Structure attachTarget = Structure.GetAttachTarget(item.WorldPosition);
@@ -35,20 +51,20 @@ namespace Barotrauma.Items.Components
if (attachTarget.Submarine != null)
{
//set to submarine-relative position
gridPos += attachTarget.Submarine.Position;
roundedGridPos += attachTarget.Submarine.Position;
attachPos += attachTarget.Submarine.Position;
gridPos += attachTarget.Submarine.DrawPosition;
roundedGridPos += attachTarget.Submarine.DrawPosition;
attachPos += attachTarget.Submarine.DrawPosition;
}
}
}
else
{
gridPos += item.Submarine.Position;
roundedGridPos += item.Submarine.Position;
attachPos += item.Submarine.Position;
gridPos += item.Submarine.DrawPosition;
roundedGridPos += item.Submarine.DrawPosition;
attachPos += item.Submarine.DrawPosition;
}
Submarine.DrawGrid(spriteBatch, 14, gridPos, roundedGridPos, alpha: 0.4f);
Submarine.DrawGrid(spriteBatch, 14, gridPos, roundedGridPos, alpha: 0.4f, color: indicatorColor);
Sprite sprite = item.Sprite;
foreach (ContainedItemSprite containedSprite in item.Prefab.ContainedSprites)
@@ -63,7 +79,7 @@ namespace Barotrauma.Items.Components
sprite.Draw(
spriteBatch,
new Vector2(attachPos.X, -attachPos.Y),
item.SpriteColor * 0.5f,
item.SpriteColor.Multiply(indicatorColor) * 0.5f,
item.RotationRad,
item.Scale, SpriteEffects.None, 0.0f);
@@ -75,7 +91,7 @@ namespace Barotrauma.Items.Components
public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
{
if (!attachable || body == null) { return; }
if (!attachable || originalBody == null) { return; }
var eventData = ExtractEventData<AttachEventData>(extraData);
@@ -115,9 +131,9 @@ namespace Barotrauma.Items.Components
if (attached)
{
DropConnectedWires(null);
if (body != null)
if (originalBody != null)
{
item.body = body;
item.body = originalBody;
item.body.Enabled = true;
}
IsActive = false;
@@ -76,7 +76,7 @@ namespace Barotrauma.Items.Components
particleEmitterCharges.Add(new ParticleEmitter(subElement));
break;
case "chargesound":
chargeSound = RoundSound.Load(subElement, false);
chargeSound = RoundSound.Load(subElement);
break;
}
}
@@ -236,7 +236,11 @@ namespace Barotrauma.Items.Components
public ItemComponent GetReplacementOrThis()
{
return ReplacedBy?.GetReplacementOrThis() ?? this;
if (ReplacedBy != null && ReplacedBy != this)
{
return ReplacedBy.GetReplacementOrThis();
}
return this;
}
public bool NeedsSoundUpdate()
@@ -511,7 +515,7 @@ namespace Barotrauma.Items.Components
if (HUDOverlay is SpriteSheet spriteSheet)
{
spriteSheet.Draw(spriteBatch,
spriteIndex: (int)(Math.Floor(Timing.TotalTimeUnpaused * HUDOverlayAnimSpeed) % spriteSheet.FrameCount),
spriteIndex: spriteSheet.GetAnimatedSpriteIndex(HUDOverlayAnimSpeed),
pos: screenSize / 2, color: Color.White, origin: HUDOverlay.Origin, rotate: 0, scale: screenSize / spriteSheet.FrameSize.ToVector2());
}
else
@@ -553,12 +553,12 @@ namespace Barotrauma.Items.Components
bool flipX = rootBody is { Dir: -1 } || flippedX;
if (flipX)
{
spriteEffects |= MathUtils.NearlyEqual(spriteRotation % 180, 90.0f) ? SpriteEffects.FlipVertically : SpriteEffects.FlipHorizontally;
spriteEffects |= SpriteEffects.FlipHorizontally;
}
bool flipY = flippedY;
if (flipY)
{
spriteEffects |= MathUtils.NearlyEqual(spriteRotation % 180, 90.0f) ? SpriteEffects.FlipHorizontally : SpriteEffects.FlipVertically;
spriteEffects |= SpriteEffects.FlipVertically;
}
contained.Item.Sprite.Draw(
@@ -434,12 +434,19 @@ namespace Barotrauma.Items.Components
foreach (FabricationRecipe fi in fabricationRecipes.Values)
{
RichString recipeTooltip = RichString.Rich(fi.TargetItem.Description);
if (fi.RequiresRecipe)
{
recipeTooltip += "\n\n" + $"‖color:{XMLExtensions.ToStringHex(GUIStyle.Red)}‖{TextManager.Get("fabricatorrequiresrecipe")}‖color:end‖";
}
recipeTooltip = RichString.Rich(recipeTooltip);
var frame = new GUIFrame(new RectTransform(new Point(itemList.Content.Rect.Width, (int)(40 * GUI.yScale)), itemList.Content.RectTransform), style: null)
{
UserData = fi,
HoverColor = Color.Gold * 0.2f,
SelectedColor = Color.Gold * 0.5f,
ToolTip = RichString.Rich(fi.TargetItem.Description)
ToolTip = recipeTooltip
};
var container = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform),
@@ -451,8 +458,8 @@ namespace Barotrauma.Items.Components
new GUIImage(new RectTransform(new Point(frame.Rect.Height,frame.Rect.Height), container.RectTransform),
itemIcon, scaleToFit: true)
{
Color = fi.TargetItem.InventoryIconColor,
ToolTip = RichString.Rich(fi.TargetItem.Description)
Color = itemIcon == fi.TargetItem.Sprite ? fi.TargetItem.SpriteColor : fi.TargetItem.InventoryIconColor,
ToolTip = recipeTooltip
};
}
@@ -461,7 +468,7 @@ namespace Barotrauma.Items.Components
{
Padding = Vector4.Zero,
AutoScaleVertical = true,
ToolTip = RichString.Rich(fi.TargetItem.Description)
ToolTip = recipeTooltip
};
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), frame.RectTransform, Anchor.BottomRight),
@@ -513,7 +520,7 @@ namespace Barotrauma.Items.Components
var nonItems = itemList.Content.Children.Where(c => c.UserData is not FabricationRecipe).ToList();
nonItems.ForEach(i => i.Visible = false);
SortItems(character: null);
SortItems(character);
FilterEntities(selectedItemCategory, itemFilterBox?.Text ?? string.Empty);
HideEmptyItemListCategories();
}
@@ -1196,6 +1203,15 @@ namespace Barotrauma.Items.Components
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), TextManager.FormatCurrency(SelectedItem.RequiredMoney),
font: GUIStyle.SmallFont);
}
if (selectedRecipe.RequiresRecipe && !AnyOneHasRecipeForItem(Character.Controlled, selectedRecipe.TargetItem))
{
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform),
TextManager.Get("fabricatorrequiresrecipe"), textColor: GUIStyle.Red, font: GUIStyle.SubHeadingFont)
{
AutoScaleHorizontal = true,
};
}
}
public void HighlightRecipe(string identifier, Color color)
@@ -92,10 +92,10 @@ namespace Barotrauma.Items.Components
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "temperatureboostsoundup":
temperatureBoostSoundUp = RoundSound.Load(subElement, false);
temperatureBoostSoundUp = RoundSound.Load(subElement);
break;
case "temperatureboostsounddown":
temperatureBoostSoundDown = RoundSound.Load(subElement, false);
temperatureBoostSoundDown = RoundSound.Load(subElement);
break;
}
}
@@ -1060,6 +1060,7 @@ namespace Barotrauma.Items.Components
int missionIndex = 0;
foreach (Mission mission in GameMain.GameSession.Missions)
{
if (!mission.Prefab.ShowSonarLabels) { continue; }
int i = 0;
foreach ((LocalizedString label, Vector2 position) in mission.SonarLabels)
{
@@ -1714,15 +1715,15 @@ namespace Barotrauma.Items.Components
foreach (Structure structure in Structure.WallList)
{
if (structure.Submarine != sub) { continue; }
CreateBlips(structure.IsHorizontal, structure.WorldPosition, structure.WorldRect);
CreateBlips(structure.IsHorizontal, structure.WorldPosition, structure.WorldRect, -structure.RotationWithFlipping);
}
foreach (var door in Door.DoorList)
{
if (door.Item.Submarine != sub || door.IsOpen) { continue; }
CreateBlips(door.IsHorizontal, door.Item.WorldPosition, door.Item.WorldRect, BlipType.Door);
CreateBlips(door.IsHorizontal, door.Item.WorldPosition, door.Item.WorldRect, rotation: 0.0f, BlipType.Door);
}
void CreateBlips(bool isHorizontal, Vector2 worldPos, Rectangle worldRect, BlipType blipType = BlipType.Default)
void CreateBlips(bool isHorizontal, Vector2 worldPos, Rectangle worldRect, float rotation, BlipType blipType = BlipType.Default)
{
Vector2 point1, point2;
if (isHorizontal)
@@ -1735,6 +1736,14 @@ namespace Barotrauma.Items.Components
point1 = new Vector2(worldPos.X, worldRect.Y);
point2 = new Vector2(worldPos.X, worldRect.Y - worldRect.Height);
}
if (!MathUtils.NearlyEqual(rotation, 0.0f))
{
float rotationRad = MathHelper.ToRadians(rotation);
point1 = MathUtils.RotatePointAroundTarget(point1, worldPos, rotationRad);
point2 = MathUtils.RotatePointAroundTarget(point2, worldPos, rotationRad);
}
CreateBlipsForLine(
point1,
point2,
@@ -973,6 +973,7 @@ namespace Barotrauma.Items.Components
}
PosToMaintain += nudgeAmount;
}
unsentChanges = true;
return true;
}
@@ -0,0 +1,180 @@
#nullable enable
using Barotrauma.Extensions;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma.Items.Components
{
internal partial class PowerDistributor : PowerTransfer, IServerSerializable, IClientSerializable
{
private partial class PowerGroup
{
private GUIFrame? frame;
private GUITextBox? nameBox;
private GUIScrollBar? ratioSlider;
private readonly List<GUITextBlock> powerUnitLabels = new List<GUITextBlock>();
private GUIFrame? divider;
public bool IsVisible { get; private set; } = true;
public void CreateGUI()
{
frame = new GUIFrame(new RectTransform(new Vector2(1f, 0.25f), distributor.groupList!.Content.RectTransform, minSize: (0, 130)), style: null);
GUIFrame groupContent = new(new RectTransform(frame.Rect.Size - new Point(10), frame.RectTransform, Anchor.Center), style: null);
GUILayoutGroup nameGroup = new(new RectTransform(new Vector2(0.65f, 0.33f), groupContent.RectTransform, Anchor.TopLeft), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true
};
GUIButton penIcon = new(new RectTransform(new Vector2(0.75f), nameGroup.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "TextBoxIcon")
{
HoverCursor = CursorState.IBeam,
OnClicked = (_, _) =>
{
nameBox!.Select();
return true;
}
};
nameBox = new GUITextBox(new RectTransform(Vector2.One, nameGroup.RectTransform), Name, font: GUIStyle.SubHeadingFont, style: "GUITextBoxNoStyle")
{
MaxTextLength = MaxNameLength,
OverflowClip = true,
TextBlock = { ForceUpperCase = ForceUpperCase.No },
OnEnterPressed = static (textBox, _) =>
{
textBox.Deselect();
return true;
}
};
nameBox.OnDeselected += (tb, _) =>
{
Name = tb.Text;
if (GameMain.Client == null) { return; }
distributor.item.CreateClientEvent(distributor, new EventData(this, EventType.NameChange));
};
GUITextBlock loadDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(0.35f, 0.33f), groupContent.RectTransform, Anchor.TopRight) { AbsoluteOffset = (5, 0) },
out GUITextBlock? _, out GUITextBlock loadDisplayUnitLabel, TextManager.Get("PowerTransferLoadLabel"), tooltip: TextManager.Get("PowerTransferTipLoad"), leftLabelFont: GUIStyle.Font);
loadDisplay.TextGetter = () => MathUtils.RoundToInt(Load).ToString();
ratioSlider = new GUIScrollBar(new RectTransform(new Vector2(1f, 0.33f), groupContent.RectTransform, Anchor.Center), barSize: 0.15f, style: "DeviceSlider")
{
Step = SupplyRatioStep,
BarScroll = SupplyRatio,
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
if (MathUtils.NearlyEqual(barScroll, SupplyRatio)) { return false; }
SupplyRatio = barScroll;
if (GameMain.Client != null)
{
distributor.item.CreateClientEvent(distributor, new EventData(this, EventType.RatioChange));
distributor.correctionTimer = CorrectionDelay;
}
return true;
}
};
ratioSlider.Bar.RectTransform.MaxSize = new Point(ratioSlider.Bar.Rect.Height);
GUITextBlock ratioDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(0.2f, 0.33f), groupContent.RectTransform, Anchor.BottomLeft),
out GUITextBlock? _, out GUITextBlock _,
rightLabelText: "%");
ratioDisplay.TextGetter = () => DisplayRatio.ToString();
GUITextBlock outputDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(0.35f, 0.33f), groupContent.RectTransform, Anchor.BottomRight) { AbsoluteOffset = (5, 0) },
out GUITextBlock? _, out GUITextBlock outputDisplayUnitLabel,
TextManager.Get("powerdistributor.supplylabel"), tooltip: TextManager.Get("PowerTransferTipPower"), leftLabelFont: GUIStyle.Font);
outputDisplay.TextGetter = () => distributor.IsShortCircuited(PowerOut) ? "err" : MathUtils.RoundToInt(distributor.CalculatePowerOut(this)).ToString();
powerUnitLabels.Add(loadDisplayUnitLabel);
powerUnitLabels.Add(outputDisplayUnitLabel);
GUITextBlock.AutoScaleAndNormalize(powerUnitLabels);
divider = new GUIFrame(new RectTransform(Vector2.UnitX, distributor.groupList!.Content.RectTransform), style: "HorizontalLine");
}
private void UpdateNameBox()
{
if (nameBox == null || nameBox.Text == DisplayName) { return; }
nameBox.Text = DisplayName?.Value ?? string.Empty;
}
private void UpdateSlider()
{
if (ratioSlider == null || MathUtils.NearlyEqual(ratioSlider.BarScroll, supplyRatio)) { return; }
ratioSlider.BarScroll = supplyRatio;
}
public void UpdateGUI()
{
IsVisible = PowerOut.Wires.Count >= 1;
frame!.Visible = IsVisible;
divider!.Visible = IsVisible && distributor.powerGroups.Last(group => group.frame!.Visible) != this;
if (distributor.prevLanguage != GameSettings.CurrentConfig.Language) { GUITextBlock.AutoScaleAndNormalize(powerUnitLabels); }
}
}
private GUIListBox? groupList;
private GUITextBlock? noConnectionsText;
protected override void CreateGUI()
{
if (GuiFrame == null) { return; }
guiContent = new GUILayoutGroup(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset })
{
Stretch = true
};
GUIFrame defaultUIContainer = new(new RectTransform(Vector2.UnitX, guiContent.RectTransform, minSize: (0, 125)), style: null)
{
CanBeFocused = false
};
CreateDefaultPowerUI(defaultUIContainer);
groupList = new(new RectTransform(Vector2.One, guiContent.RectTransform)) { Enabled = false };
noConnectionsText = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.0f), groupList.Content.RectTransform, Anchor.Center), TextManager.Get("powerdistributor.noconnections"), wrap: true)
{
Visible = false
};
powerGroups.ForEach(group => group.CreateGUI());
}
public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
{
if (GuiFrame == null) { return; }
powerGroups.ForEach(group => group.UpdateGUI());
noConnectionsText!.Visible = powerGroups.None(group => group.IsVisible);
base.UpdateHUDComponentSpecific(character, deltaTime, cam);
}
#region Networking
public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData? extraData = null) => SharedEventWrite(msg, extraData);
public void ClientEventRead(IReadMessage msg, float sendingTime)
{
int msgStartPos = msg.BitPosition;
SharedEventRead(msg, out EventType eventType, out PowerGroup powerGroup, out string newName, out float newRatio);
if (correctionTimer > 0f)
{
int msgBits = msg.BitPosition - msgStartPos;
msg.BitPosition -= msgBits;
StartDelayedCorrection(msg.ExtractBits(msgBits), sendingTime);
return;
}
switch (eventType)
{
case EventType.NameChange:
powerGroup.Name = newName;
break;
case EventType.RatioChange:
powerGroup.SupplyRatio = newRatio;
break;
}
}
#endregion
}
}
@@ -6,125 +6,84 @@ namespace Barotrauma.Items.Components
{
partial class PowerTransfer : Powered
{
public override bool RecreateGUIOnResolutionChange => true;
protected GUIComponent guiContent;
private GUITickBox powerIndicator;
private GUITickBox highVoltageIndicator;
private GUITickBox lowVoltageIndicator;
private GUITextBlock powerLabel, loadLabel;
protected GUITextBlock powerDisplay, loadDisplay;
private LanguageIdentifier prevLanguage;
protected LanguageIdentifier prevLanguage;
partial void InitProjectSpecific(XElement element)
{
if (GuiFrame == null) { return; }
CreateGUI();
prevLanguage = GameSettings.CurrentConfig.Language;
}
var paddedFrame = new GUIFrame(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset },
style: null)
protected override void CreateGUI()
{
if (GuiFrame == null) { return; }
guiContent = new GUIFrame(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset }, style: null)
{
CanBeFocused = false
};
CreateDefaultPowerUI(guiContent);
}
var lightsArea = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1), paddedFrame.RectTransform, Anchor.CenterLeft))
protected void CreateDefaultPowerUI(GUIComponent parent)
{
GUILayoutGroup lightsArea = new(new RectTransform(new Vector2(0.4f, 1f), parent.RectTransform, Anchor.CenterLeft))
{
Stretch = true
};
powerIndicator = new GUITickBox(new RectTransform(new Vector2(1, 0.33f), lightsArea.RectTransform),
TextManager.Get("PowerTransferPowered"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightGreen")
{
CanBeFocused = false
};
highVoltageIndicator = new GUITickBox(new RectTransform(new Vector2(1, 0.33f), lightsArea.RectTransform),
TextManager.Get("PowerTransferHighVoltage"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
{
ToolTip = TextManager.Get("PowerTransferTipOvervoltage"),
Enabled = false
};
lowVoltageIndicator = new GUITickBox(new RectTransform(new Vector2(1, 0.33f), lightsArea.RectTransform),
TextManager.Get("PowerTransferLowVoltage"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRed")
{
ToolTip = TextManager.Get("PowerTransferTipLowvoltage"),
Enabled = false
};
powerIndicator.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
highVoltageIndicator.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
lowVoltageIndicator.TextBlock.OverrideTextColor(GUIStyle.TextColorNormal);
powerIndicator = GUI.CreateIndicatorLight(new RectTransform(new Vector2(1, 0.33f), lightsArea.RectTransform),
"IndicatorLightGreen", TextManager.Get("PowerTransferPowered"));
highVoltageIndicator = GUI.CreateIndicatorLight(new RectTransform(new Vector2(1, 0.33f), lightsArea.RectTransform),
"IndicatorLightRed", TextManager.Get("PowerTransferHighVoltage"), TextManager.Get("PowerTransferTipOvervoltage"));
lowVoltageIndicator = GUI.CreateIndicatorLight(new RectTransform(new Vector2(1, 0.33f), lightsArea.RectTransform),
"IndicatorLightRed", TextManager.Get("PowerTransferLowVoltage"), TextManager.Get("PowerTransferTipLowvoltage"));
GUITextBlock.AutoScaleAndNormalize(powerIndicator.TextBlock, highVoltageIndicator.TextBlock, lowVoltageIndicator.TextBlock);
var textContainer = new GUIFrame(new RectTransform(new Vector2(0.58f, 1.0f), paddedFrame.RectTransform, Anchor.CenterRight), style: null);
var upperTextArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), textContainer.RectTransform, Anchor.TopLeft), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true
};
var lowerTextArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), textContainer.RectTransform, Anchor.BottomLeft), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true
};
GUIFrame textContainer = new(new RectTransform(new Vector2(0.58f, 1f), parent.RectTransform, Anchor.CenterRight), style: null);
powerLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), upperTextArea.RectTransform),
TextManager.Get("PowerTransferPowerLabel"), textColor: GUIStyle.TextColorBright, font: GUIStyle.LargeFont, textAlignment: Alignment.CenterRight)
{
ToolTip = TextManager.Get("PowerTransferTipPower")
};
loadLabel = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1), lowerTextArea.RectTransform),
TextManager.Get("PowerTransferLoadLabel"), textColor: GUIStyle.TextColorBright, font: GUIStyle.LargeFont, textAlignment: Alignment.CenterRight)
{
ToolTip = TextManager.Get("PowerTransferTipLoad")
};
powerDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(1f, 0.5f), textContainer.RectTransform, Anchor.TopLeft),
out powerLabel, out GUITextBlock unitLabel1, TextManager.Get("PowerTransferPowerLabel"), TextManager.Get("kilowatt"), TextManager.Get("PowerTransferTipPower"));
var digitalBackground = new GUIFrame(new RectTransform(new Vector2(0.55f, 0.8f), upperTextArea.RectTransform), style: "DigitalFrameDark");
var powerText = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.95f), digitalBackground.RectTransform, Anchor.Center),
"", font: GUIStyle.DigitalFont, textColor: GUIStyle.TextColorDark)
powerDisplay.TextGetter = () =>
{
TextAlignment = Alignment.CenterRight,
ToolTip = TextManager.Get("PowerTransferTipPower"),
TextGetter = () => {
float currPower = powerLoad < 0 ? -powerLoad: 0;
if (this is not RelayComponent && PowerConnections != null && PowerConnections.Count > 0 && PowerConnections[0].Grid != null)
{
currPower = PowerConnections[0].Grid.Power;
}
return ((int)Math.Round(currPower)).ToString();
}
};
var kw1 = new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.5f), upperTextArea.RectTransform),
TextManager.Get("kilowatt"), textColor: GUIStyle.TextColorNormal, font: GUIStyle.Font)
{
Padding = Vector4.Zero,
TextAlignment = Alignment.BottomCenter
};
digitalBackground = new GUIFrame(new RectTransform(new Vector2(0.55f, 0.8f), lowerTextArea.RectTransform), style: "DigitalFrameDark");
var loadText = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.95f), digitalBackground.RectTransform, Anchor.Center),
"", font: GUIStyle.DigitalFont, textColor: GUIStyle.TextColorDark)
{
TextAlignment = Alignment.CenterRight,
ToolTip = TextManager.Get("PowerTransferTipLoad"),
TextGetter = () =>
float currPower = powerLoad < 0 ? -powerLoad : 0;
if (this is not RelayComponent && PowerConnections != null && PowerConnections.Count > 0 && PowerConnections[0].Grid != null)
{
float load = PowerLoad;
if (this is RelayComponent relay)
{
load = relay.DisplayLoad;
}
else if (load < 0)
{
load = 0;
}
return ((int)Math.Round(load)).ToString();
currPower = PowerConnections[0].Grid.Power;
}
return MathUtils.RoundToInt(currPower).ToString();
};
var kw2 = new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.5f), lowerTextArea.RectTransform),
TextManager.Get("kilowatt"), textColor: GUIStyle.TextColorNormal, font: GUIStyle.Font)
loadDisplay = GUI.CreateDigitalDisplay(new RectTransform(new Vector2(1f, 0.5f), textContainer.RectTransform, Anchor.BottomLeft),
out loadLabel, out GUITextBlock unitLabel2, TextManager.Get("PowerTransferLoadLabel"), TextManager.Get("kilowatt"), TextManager.Get("PowerTransferTipLoad"));
loadDisplay.TextGetter = () =>
{
Padding = Vector4.Zero,
TextAlignment = Alignment.BottomCenter
float load = PowerLoad;
if (this is RelayComponent relay)
{
load = relay.DisplayLoad;
}
else if (load < 0)
{
load = 0;
}
return MathUtils.RoundToInt(load).ToString();
};
GUITextBlock.AutoScaleAndNormalize(powerLabel, loadLabel);
GUITextBlock.AutoScaleAndNormalize(true, true, powerText, loadText);
GUITextBlock.AutoScaleAndNormalize(kw1, kw2);
prevLanguage = GameSettings.CurrentConfig.Language;
GUITextBlock.AutoScaleAndNormalize(true, true, powerDisplay, loadDisplay);
GUITextBlock.AutoScaleAndNormalize(unitLabel1, unitLabel2);
}
public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
@@ -12,7 +12,7 @@
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "poweronsound":
powerOnSound = RoundSound.Load(subElement, false);
powerOnSound = RoundSound.Load(subElement);
break;
}
}
@@ -4,10 +4,6 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -28,7 +24,7 @@ namespace Barotrauma.Items.Components
private readonly List<ParticleEmitter> particleEmitterHitCharacter = new List<ParticleEmitter>();
private readonly List<(RelatedItem relatedItem, ParticleEmitter emitter)> particleEmitterHitItem = new List<(RelatedItem relatedItem, ParticleEmitter emitter)>();
private float prevProgressBarState;
private float prevProgressBarState = 1;
private Item prevProgressBarTarget = null;
partial void InitProjSpecific(ContentXElement element)
@@ -1,4 +1,4 @@
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
@@ -150,16 +150,16 @@ namespace Barotrauma.Items.Components
crosshairPointerSprite = new Sprite(subElement, path: textureDir);
break;
case "startmovesound":
startMoveSound = RoundSound.Load(subElement, false);
startMoveSound = RoundSound.Load(subElement);
break;
case "endmovesound":
endMoveSound = RoundSound.Load(subElement, false);
endMoveSound = RoundSound.Load(subElement);
break;
case "movesound":
moveSound = RoundSound.Load(subElement, false);
moveSound = RoundSound.Load(subElement);
break;
case "chargesound":
chargeSound = RoundSound.Load(subElement, false);
chargeSound = RoundSound.Load(subElement);
break;
case "particleemitter":
particleEmitters.Add(new ParticleEmitter(subElement));
@@ -357,6 +357,18 @@ namespace Barotrauma
#if DEBUG
toolTip += $" ({item.Prefab.Identifier})";
#endif
if (!item.Prefab.UnlockedRecipeInToolTip.IsEmpty && GameMain.GameSession is { } GameSession)
{
if (GameSession.UnlockedRecipes.Contains(item.Prefab.UnlockedRecipeInToolTip))
{
toolTip += TextManager.Get("unlockedrecipe.true");
}
else
{
toolTip += $"\n‖color:{XMLExtensions.ToStringHex(GUIStyle.Yellow)}‖{TextManager.Get("unlockedrecipe.false")}‖color:end‖";
}
}
if (PlayerInput.KeyDown(InputType.ContextualCommand))
{
toolTip += $"\n‖color:gui.blue‖{TextManager.ParseInputTypes(TextManager.Get("itemmsgcontextualorders"))}‖color:end‖";
@@ -365,7 +377,8 @@ namespace Barotrauma
{
var colorStr = XMLExtensions.ToStringHex(Color.LightGray * 0.7f);
toolTip += $"\n‖color:{colorStr}‖{TextManager.Get("itemmsg.morreoptionsavailable")}‖color:end‖";
}
}
return RichString.Rich(toolTip);
}
@@ -425,9 +438,9 @@ namespace Barotrauma
}
}
public Inventory GetReplacementOrThiS()
public Inventory GetReplacementOrThis()
{
return ReplacedBy?.GetReplacementOrThiS() ?? this;
return ReplacedBy?.GetReplacementOrThis() ?? this;
}
public virtual void CreateSlots()
@@ -1255,7 +1268,7 @@ namespace Barotrauma
container.AllowDragAndDrop &&
inventory.CanBePut(DraggingItems.FirstOrDefault());
bool isTargetingValidCharacter = IsValidTargetForDragDropGive(Character.Controlled, Character.Controlled.FocusedCharacter);
bool isTargetingValidCharacter = IsValidTargetForDragDropGive(Character.Controlled, Character.Controlled.FocusedCharacter, DraggingItems);
if (DraggingItemToWorld && (isTargetingValidContainer || isTargetingValidCharacter))
{
@@ -1418,11 +1431,13 @@ namespace Barotrauma
}
}
private static bool IsValidTargetForDragDropGive(Character giver, Character receiver)
private static bool IsValidTargetForDragDropGive(Character giver, Character receiver, IEnumerable<Item> draggedItems)
{
if (giver == null || receiver == null) { return false; }
if (giver == null || receiver == null || draggedItems.None()) { return false; }
if (receiver == giver) { return false; }
return receiver.IsInventoryAccessibleTo(giver, IsDragAndDropGiveAllowed ? CharacterInventory.AccessLevel.Allowed : CharacterInventory.AccessLevel.Limited);
return
receiver.IsInventoryAccessibleTo(giver, IsDragAndDropGiveAllowed ? CharacterInventory.AccessLevel.Allowed : CharacterInventory.AccessLevel.Limited) &&
receiver.Inventory.CanBePut(draggedItems.FirstOrDefault(), InvSlotType.Any);
}
private static bool CanSelectSlot(SlotReference selectedSlot)
@@ -1651,7 +1666,7 @@ namespace Barotrauma
(LocalizedString, Color) GetDragLabelTextAndColor(bool mouseOnHealthInterface)
{
bool useDragDropGive = IsValidTargetForDragDropGive(Character.Controlled, Character.Controlled.FocusedCharacter);
bool useDragDropGive = IsValidTargetForDragDropGive(Character.Controlled, Character.Controlled.FocusedCharacter, DraggingItems);
Color toolTipColor = Color.LightGreen;
@@ -316,9 +316,6 @@ namespace Barotrauma
if (worldPosition.X + extents.X > worldView.Right || worldPosition.X + extents.Width < worldView.X) { return false; }
if (worldPosition.Y + extents.Height < worldView.Y - worldView.Height || worldPosition.Y + extents.Y > worldView.Y) { return false; }
if (extents.Width * Screen.Selected.Cam.Zoom < 1.0f) { return false; }
if (extents.Height * Screen.Selected.Cam.Zoom < 1.0f) { return false; }
return true;
}
@@ -327,7 +324,7 @@ namespace Barotrauma
Draw(spriteBatch, editing, back, overrideColor: null);
}
public void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Color? overrideColor = null)
public void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Color? overrideColor = null, float? overrideDepth = null)
{
if (!Visible || (!editing && IsHidden) || !SubEditorScreen.IsLayerVisible(this)) { return; }
@@ -395,7 +392,7 @@ namespace Barotrauma
}
}
float depth = GetDrawDepth();
float depth = overrideDepth ?? GetDrawDepth();
if (isWiringMode && isLogic && !PlayerInput.IsShiftDown()) { depth = 0.01f; }
if (activeSprite != null)
{
@@ -427,7 +424,7 @@ namespace Barotrauma
textureScale: Vector2.One * Scale,
depth: d);
}
DrawDecorativeSprites(spriteBatch, DrawPosition, flippedX && Prefab.CanSpriteFlipX, flippedY && Prefab.CanSpriteFlipY, rotation: 0, depth, overrideColor);
DrawDecorativeSprites(spriteBatch, DrawPosition, FlippedX && Prefab.CanSpriteFlipX, FlippedY && Prefab.CanSpriteFlipY, rotation: 0, depth, overrideColor);
}
}
else
@@ -448,7 +445,7 @@ namespace Barotrauma
Prefab.DamagedInfectedSprite?.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, Infector.HealthColor, Prefab.DamagedInfectedSprite.Origin, RotationRad, Scale, activeSprite.effects, depth - 0.002f);
}
DrawDecorativeSprites(spriteBatch, DrawPosition, flippedX && Prefab.CanSpriteFlipX, flippedY && Prefab.CanSpriteFlipY, -RotationRad, depth, overrideColor);
DrawDecorativeSprites(spriteBatch, DrawPosition, FlippedX && Prefab.CanSpriteFlipX, FlippedY && Prefab.CanSpriteFlipY, -RotationRad, depth, overrideColor);
}
}
else if (body.Enabled)
@@ -524,8 +521,8 @@ namespace Barotrauma
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier, -RotationRad) * Scale;
if (flippedX && Prefab.CanSpriteFlipX) { offset.X = -offset.X; }
if (flippedY && Prefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
if (FlippedX && Prefab.CanSpriteFlipX) { offset.X = -offset.X; }
if (FlippedY && Prefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + offset.X, -(DrawPosition.Y + offset.Y)), color, decorativeSprite.Sprite.Origin,
rotation, decorativeSprite.GetScale(ref spriteAnimState[decorativeSprite].ScaleState, spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, activeSprite.effects,
depth: depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth));
@@ -543,7 +540,7 @@ namespace Barotrauma
//causing them to be removed from the list
for (int i = drawableComponents.Count - 1; i >= 0; i--)
{
drawableComponents[i].Draw(spriteBatch, editing, depth, overrideColor);
drawableComponents[i].Draw(spriteBatch, editing && !GameMain.SubEditorScreen.TransformWidgetSelected, depth, overrideColor);
}
if (GameMain.DebugDraw)
@@ -813,6 +810,8 @@ namespace Barotrauma
}
if (Screen.Selected != GameMain.SubEditorScreen) { return; }
if (Character.Controlled == null) { activeHUDs.Clear(); }
if (GameMain.SubEditorScreen.TransformWidgetSelected) { return; }
if (GetComponent<ElectricalDischarger>() is { } discharger)
{
@@ -826,8 +825,6 @@ namespace Barotrauma
}
}
if (Character.Controlled == null) { activeHUDs.Clear(); }
foreach (ItemComponent ic in components)
{
ic.UpdateEditing(deltaTime);
@@ -2341,6 +2338,7 @@ namespace Barotrauma
}
}
bool onInsertedEffectsAppliedOnPreviousRound = msg.ReadBoolean();
byte bodyType = msg.ReadByte();
bool spawnedInOutpost = msg.ReadBoolean();
bool allowStealing = msg.ReadBoolean();
@@ -2453,6 +2451,10 @@ namespace Barotrauma
AllowStealing = allowStealing,
Quality = quality
};
if (onInsertedEffectsAppliedOnPreviousRound)
{
item.OnInsertedEffectsApplied = item.OnInsertedEffectsAppliedOnPreviousRound = true;
}
}
catch (Exception e)
{