v1.5.7.0 (Summer Update)

This commit is contained in:
Regalis11
2024-06-18 16:49:51 +03:00
parent 4a63dacbce
commit 230d1b6e78
263 changed files with 7792 additions and 2845 deletions
@@ -79,7 +79,8 @@ namespace Barotrauma.Items.Components
set;
}
[Serialize(false, IsPropertySaveable.No, description: "If true, the contained state indicator calculates how full the item is based on the total amount of items that can be stacked inside it, as opposed to how many of the inventory slots are occupied.")]
[Serialize(false, IsPropertySaveable.No, description: "If true, the contained state indicator calculates how full the item is based on the total amount of items that can be stacked inside it, as opposed to how many of the inventory slots are occupied." +
" Note that only items in the main container or in the subcontainer are counted, depending on which container the first containable item match is found in. The item determining this can be defined with ContainedStateIndicatorSlot")]
public bool ShowTotalStackCapacityInContainedStateIndicator { get; set; }
[Serialize(false, IsPropertySaveable.No, description: "Should the inventory of this item be kept open when the item is equipped by a character.")]
@@ -274,8 +275,14 @@ namespace Barotrauma.Items.Components
}
}
itemsPerSlot.Sort((i1, i2) => i1.First().Name.CompareTo(i2.First().Name));
foreach (var items in itemsPerSlot)
var sortedItems = itemsPerSlot
.OrderBy(i => i.First().Name)
//if there's multiple items with the same name, sort largest stacks first
.ThenByDescending(i => i.Count)
//same name and stack size, sort items with most items inside first
.ThenByDescending(i => i.First().ContainedItems.Count());
foreach (var items in sortedItems)
{
int firstFreeSlot = -1;
for (int i = 0; i < Inventory.Capacity; i++)
@@ -591,7 +598,8 @@ namespace Barotrauma.Items.Components
contained.Item.Scale,
spriteEffects,
depth: containedSpriteDepth);
contained.Item.DrawDecorativeSprites(spriteBatch, itemPos, flipX,flipY, (contained.Item.body == null ? 0.0f : contained.Item.body.DrawRotation), containedSpriteDepth);
contained.Item.DrawDecorativeSprites(spriteBatch, itemPos, flipX,flipY, (contained.Item.body == null ? 0.0f : contained.Item.body.DrawRotation),
containedSpriteDepth, overrideColor);
foreach (ItemContainer ic in contained.Item.GetComponents<ItemContainer>())
{
@@ -40,7 +40,7 @@ namespace Barotrauma.Items.Components
partial void SetLightSourceState(bool enabled, float brightness)
{
if (Light == null) { return; }
if (item.HiddenInGame) { enabled = false; }
if (item.IsHidden) { enabled = false; }
Light.Enabled = enabled;
lightColorMultiplier = brightness;
if (enabled)
@@ -429,7 +429,7 @@ namespace Barotrauma.Items.Components
{
if (it?.Submarine == null) { return false; }
if (item.Submarine == null || !item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true)) { return false; }
if (it.NonInteractable || it.HiddenInGame) { return false; }
if (it.NonInteractable || it.IsHidden) { return false; }
if (it.GetComponent<Pickable>() == null) { return false; }
var holdable = it.GetComponent<Holdable>();
@@ -470,10 +470,10 @@ namespace Barotrauma.Items.Components
scissorComponent = new GUIScissorComponent(new RectTransform(Vector2.One, submarineContainer.RectTransform, Anchor.Center));
miniMapContainer = new GUIFrame(new RectTransform(Vector2.One, scissorComponent.Content.RectTransform, Anchor.Center), style: null) { CanBeFocused = false };
ImmutableHashSet<Item> hullPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.HiddenInGame && !it.NonInteractable && it.Prefab.ShowInStatusMonitor && (it.GetComponent<Door>() != null || it.GetComponent<Turret>() != null)).ToImmutableHashSet();
ImmutableHashSet<Item> hullPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.IsHidden && !it.NonInteractable && it.Prefab.ShowInStatusMonitor && (it.GetComponent<Door>() != null || it.GetComponent<Turret>() != null)).ToImmutableHashSet();
miniMapFrame = CreateMiniMap(item.Submarine, submarineContainer, MiniMapSettings.Default, hullPointsOfInterest, out hullStatusComponents);
IEnumerable<Item> electricalPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.HiddenInGame && !it.NonInteractable && it.GetComponent<Repairable>() != null);
IEnumerable<Item> electricalPointsOfInterest = Item.ItemList.Where(it => item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true) && !it.IsHidden && !it.NonInteractable && it.GetComponent<Repairable>() != null);
electricalFrame = CreateMiniMap(item.Submarine, miniMapContainer, new MiniMapSettings(createHullElements: false), electricalPointsOfInterest, out electricalMapComponents);
Dictionary<MiniMapGUIComponent, GUIComponent> electricChildren = new Dictionary<MiniMapGUIComponent, GUIComponent>();
@@ -566,7 +566,7 @@ namespace Barotrauma.Items.Components
displayedSubs.Add(item.Submarine);
displayedSubs.AddRange(item.Submarine.DockedTo.Where(s => s.TeamID == item.Submarine.TeamID));
subEntities = MapEntity.MapEntityList.Where(me => (item.Submarine is { } sub && sub.IsEntityFoundOnThisSub(me, includingConnectedSubs: true, allowDifferentType: false)) && !me.HiddenInGame).OrderByDescending(w => w.SpriteDepth).ToList();
subEntities = MapEntity.MapEntityList.Where(me => (item.Submarine is { } sub && sub.IsEntityFoundOnThisSub(me, includingConnectedSubs: true, allowDifferentType: false)) && !me.IsHidden).OrderByDescending(w => w.SpriteDepth).ToList();
BakeSubmarine(item.Submarine, parentRect);
elementSize = GuiFrame.Rect.Size;
@@ -763,7 +763,7 @@ namespace Barotrauma.Items.Components
worldBorders.Location += item.Submarine.WorldPosition.ToPoint();
foreach (Gap gap in Gap.GapList)
{
if (gap.IsRoomToRoom || gap.linkedTo.Count == 0 || gap.Submarine != item.Submarine || gap.ConnectedDoor != null || gap.HiddenInGame) { continue; }
if (gap.IsRoomToRoom || gap.linkedTo.Count == 0 || gap.Submarine != item.Submarine || gap.ConnectedDoor != null || gap.IsHidden) { continue; }
RectangleF entityRect = ScaleRectToUI(gap, miniMapFrame.Rect, worldBorders);
Vector2 scale = new Vector2(entityRect.Size.X / spriteSize.X, entityRect.Size.Y / spriteSize.Y) * 2.0f;
@@ -930,7 +930,7 @@ namespace Barotrauma.Items.Components
if (DisplayAsSameItem(it.Prefab, searchedPrefab))
{
// ignore items on players and hidden inventories
if (it.FindParentInventory(inv => inv is CharacterInventory || inv is ItemInventory { Owner: Item { HiddenInGame: true }}) is { }) { continue; }
if (it.FindParentInventory(inv => inv is CharacterInventory || inv is ItemInventory { Owner: Item { IsHidden: true }}) is { }) { continue; }
if (it.FindParentInventory(inventory => inventory is ItemInventory { Owner: Item { ParentInventory: null } }) is ItemInventory parent)
{
@@ -1112,7 +1112,7 @@ namespace Barotrauma.Items.Components
if (ShowHullIntegrity)
{
float amount = 1f + hullData.LinkedHulls.Count;
gapOpenSum = hull.ConnectedGaps.Concat(hullData.LinkedHulls.SelectMany(h => h.ConnectedGaps)).Where(g => g.linkedTo.Count == 1 && !g.HiddenInGame).Sum(g => g.Open) / amount;
gapOpenSum = hull.ConnectedGaps.Concat(hullData.LinkedHulls.SelectMany(h => h.ConnectedGaps)).Where(g => g.linkedTo.Count == 1 && !g.IsHidden).Sum(g => g.Open) / amount;
borderColor = Color.Lerp(neutralColor, GUIStyle.Red, Math.Min(gapOpenSum, 1.0f));
}
@@ -1557,7 +1557,7 @@ namespace Barotrauma.Items.Components
{
if (linkedEntity is Hull linkedHull)
{
if (linkedHulls.Contains(linkedHull) || linkedHull.HiddenInGame) { continue; }
if (linkedHulls.Contains(linkedHull) || linkedHull.IsHidden) { continue; }
linkedHulls.Add(linkedHull);
GetLinkedHulls(linkedHull, linkedHulls);
}
@@ -1737,7 +1737,7 @@ namespace Barotrauma.Items.Components
bool IsPartofSub(MapEntity entity)
{
if (entity.Submarine != sub && !connectedSubs.Contains(entity.Submarine) || entity.HiddenInGame) { return false; }
if (entity.Submarine != sub && !connectedSubs.Contains(entity.Submarine) || entity.IsHidden) { return false; }
return sub.IsEntityFoundOnThisSub(entity, true);
}
@@ -1186,7 +1186,7 @@ namespace Barotrauma.Items.Components
foreach (DockingPort dockingPort in DockingPort.List)
{
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
if (dockingPort.Item.HiddenInGame) { continue; }
if (dockingPort.Item.IsHidden) { continue; }
if (dockingPort.Item.Submarine == null) { continue; }
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
// docking ports should be shown even if defined as not, if the submarine is the same as the sonar's
@@ -60,7 +60,7 @@ namespace Barotrauma.Items.Components
public override bool ShouldDrawHUD(Character character)
{
if (item.HiddenInGame) { return false; }
if (item.IsHidden) { return false; }
if (!HasRequiredItems(character, false) || character.SelectedItem != item) { return false; }
if (character.IsTraitor && item.ConditionPercentage > MinSabotageCondition) { return true; }
if (item.ConditionPercentageRelativeToDefaultMaxCondition < RepairThreshold) { return true; }
@@ -224,7 +224,7 @@ namespace Barotrauma.Items.Components
partial void UpdateProjSpecific(float deltaTime)
{
if (item.HiddenInGame) { return; }
if (item.IsHidden) { return; }
if (FakeBrokenTimer > 0.0f)
{
item.FakeBroken = true;
@@ -397,6 +397,12 @@ namespace Barotrauma.Items.Components
GUI.DrawString(spriteBatch,
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + 20), "Condition: " + (int)item.Condition + "/" + (int)item.MaxCondition,
GUIStyle.Orange);
if (MaxStressDeteriorationMultiplier > 1.0f)
{
GUI.DrawString(spriteBatch,
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + 40), "Stress multiplier: " + StressDeteriorationMultiplier.ToString("0.00"),
GUIStyle.Red);
}
}
}
@@ -303,6 +303,17 @@ namespace Barotrauma.Items.Components
CreateClientEvent(new CircuitBoxRenameLabelEvent(label.ID, color, header, body));
}
public void SetConnectionLabelOverrides(CircuitBoxInputOutputNode node, Dictionary<string, string> newOverrides)
{
if (GameMain.NetworkMember is null)
{
node.ReplaceAllConnectionLabelOverrides(newOverrides);
return;
}
CreateClientEvent(new CircuitBoxRenameConnectionLabelsEvent(node.NodeType, newOverrides.ToNetDictionary()));
}
public void ResizeNode(CircuitBoxNode node, CircuitBoxResizeDirection dir, Vector2 amount)
{
if (Locked) { return; }
@@ -528,6 +539,12 @@ namespace Barotrauma.Items.Components
_ => node.Position
};
}
foreach (var labelOverride in data.LabelOverrides)
{
RenameConnectionLabelsInternal(labelOverride.Type, labelOverride.Override.ToDictionary());
}
wasInitializedByServer = true;
break;
}
@@ -556,6 +573,12 @@ namespace Barotrauma.Items.Components
ResizeLabelInternal(data.ID, data.Position, data.Size);
break;
}
case CircuitBoxOpcode.RenameConnections:
{
var data = INetSerializableStruct.Read<CircuitBoxRenameConnectionLabelsEvent>(msg);
RenameConnectionLabelsInternal(data.Type, data.Override.ToDictionary());
break;
}
default:
throw new ArgumentOutOfRangeException(nameof(header), header, "This opcode cannot be handled using entity events");
}
@@ -292,8 +292,17 @@ namespace Barotrauma.Items.Components
if (wire.HiddenInGame && Screen.Selected == GameMain.GameScreen) { continue; }
Connection recipient = wire.OtherConnection(this);
LocalizedString label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
if (wire.Locked) { label += "\n" + TextManager.Get("ConnectionLocked"); }
LocalizedString label;
if (wire.Item.IsLayerHidden)
{
label = TextManager.Get("ConnectionLocked");
}
else
{
label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
if (wire.Locked) { label += "\n" + TextManager.Get("ConnectionLocked"); }
}
DrawWire(spriteBatch, wire, position, wirePosition, equippedWire, panel, label);
wirePosition.Y += wireInterval;
@@ -494,7 +503,7 @@ namespace Barotrauma.Items.Components
ConnectionPanel.HighlightedWire = wire;
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring || panel.AlwaysAllowRewiring;
if (allowRewiring && (!wire.Locked && !panel.Locked && !panel.TemporarilyLocked || Screen.Selected == GameMain.SubEditorScreen))
if (allowRewiring && (!wire.Locked && !wire.Item.IsLayerHidden && !panel.Locked && !panel.TemporarilyLocked || Screen.Selected == GameMain.SubEditorScreen))
{
//start dragging the wire
if (PlayerInput.PrimaryMouseButtonHeld()) { DraggingConnected = wire; }
@@ -283,12 +283,12 @@ namespace Barotrauma.Items.Components
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", InputType.Use));
textColors.Add(GUIStyle.Green);
}
if (target.CharacterHealth.UseHealthWindow && !target.DisableHealthWindow && equipper?.FocusedCharacter == target && equipper.CanInteractWith(target, 160f, false))
if (equipper?.FocusedCharacter == target && target.CanBeHealedBy(equipper, checkFriendlyTeam: false))
{
texts.Add(CharacterHUD.GetCachedHudText("HealHint", InputType.Health));
textColors.Add(GUIStyle.Green);
}
if (target.CanBeDragged)
if (target.CanBeDraggedBy(Character.Controlled))
{
texts.Add(CharacterHUD.GetCachedHudText("GrabHint", InputType.Grab));
textColors.Add(GUIStyle.Green);
@@ -196,7 +196,7 @@ namespace Barotrauma.Items.Components
Vector2 particlePos = GetRelativeFiringPosition();
foreach (ParticleEmitter emitter in particleEmitters)
{
emitter.Emit(1.0f, particlePos, hullGuess: null, angle: -rotation, particleRotation: rotation);
emitter.Emit(1.0f, particlePos, hullGuess: null, angle: -Rotation, particleRotation: Rotation);
}
}
@@ -213,7 +213,7 @@ namespace Barotrauma.Items.Components
if (crosshairSprite != null)
{
Vector2 itemPos = cam.WorldToScreen(new Vector2(item.WorldRect.X + transformedBarrelPos.X, item.WorldRect.Y - transformedBarrelPos.Y));
Vector2 turretDir = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
Vector2 turretDir = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation));
Vector2 mouseDiff = itemPos - PlayerInput.MousePosition;
crosshairPos = new Vector2(
@@ -268,7 +268,7 @@ namespace Barotrauma.Items.Components
foreach (ParticleEmitter emitter in particleEmitterCharges)
{
// color is currently not connected to ammo type, should be updated when ammo is changed
emitter.Emit(deltaTime, particlePos, hullGuess: null, angle: -rotation, particleRotation: rotation, sizeMultiplier: sizeMultiplier, colorMultiplier: emitter.Prefab.Properties.ColorMultiplier);
emitter.Emit(deltaTime, particlePos, hullGuess: null, angle: -Rotation, particleRotation: Rotation, sizeMultiplier: sizeMultiplier, colorMultiplier: emitter.Prefab.Properties.ColorMultiplier);
}
if (chargeSoundChannel == null || !chargeSoundChannel.IsPlaying)
@@ -339,7 +339,7 @@ namespace Barotrauma.Items.Components
if (crosshairSprite != null)
{
Vector2 itemPos = cam.WorldToScreen(item.WorldPosition);
Vector2 turretDir = new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation));
Vector2 turretDir = new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation));
Vector2 mouseDiff = itemPos - PlayerInput.MousePosition;
crosshairPos = new Vector2(
@@ -372,7 +372,7 @@ namespace Barotrauma.Items.Components
recoilOffset = RecoilDistance;
}
}
return new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset;
return new Vector2((float)Math.Cos(Rotation), (float)Math.Sin(Rotation)) * recoilOffset;
}
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1, Color? overrideColor = null)
@@ -388,13 +388,13 @@ namespace Barotrauma.Items.Components
railSprite?.Draw(spriteBatch,
drawPos,
overrideColor ?? item.SpriteColor,
rotation + MathHelper.PiOver2, item.Scale,
Rotation + MathHelper.PiOver2, item.Scale,
SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth));
barrelSprite?.Draw(spriteBatch,
drawPos - GetRecoilOffset() * item.Scale,
overrideColor ?? item.SpriteColor,
rotation + MathHelper.PiOver2, item.Scale,
Rotation + MathHelper.PiOver2, item.Scale,
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
float chargeRatio = currentChargeTime / MaxChargeTime;
@@ -402,9 +402,9 @@ namespace Barotrauma.Items.Components
foreach ((Sprite chargeSprite, Vector2 position) in chargeSprites)
{
chargeSprite?.Draw(spriteBatch,
drawPos - MathUtils.RotatePoint(new Vector2(position.X * chargeRatio, position.Y * chargeRatio) * item.Scale, rotation + MathHelper.PiOver2),
drawPos - MathUtils.RotatePoint(new Vector2(position.X * chargeRatio, position.Y * chargeRatio) * item.Scale, Rotation + MathHelper.PiOver2),
item.SpriteColor,
rotation + MathHelper.PiOver2, item.Scale,
Rotation + MathHelper.PiOver2, item.Scale,
SpriteEffects.None, item.SpriteDepth + (chargeSprite.Depth - item.Sprite.Depth));
}
@@ -427,9 +427,9 @@ namespace Barotrauma.Items.Components
float newPositionOffset = barrelPositionModifier * SpinningBarrelDistance;
spinningBarrel.Draw(spriteBatch,
drawPos - MathUtils.RotatePoint(new Vector2(newPositionOffset, 0f) * item.Scale, rotation + MathHelper.PiOver2),
drawPos - MathUtils.RotatePoint(new Vector2(newPositionOffset, 0f) * item.Scale, Rotation + MathHelper.PiOver2),
Color.Lerp(overrideColor ?? item.SpriteColor, newColorModifier, 0.8f),
rotation + MathHelper.PiOver2, item.Scale,
Rotation + MathHelper.PiOver2, item.Scale,
SpriteEffects.None, newDepth);
}
}
@@ -475,9 +475,9 @@ namespace Barotrauma.Items.Components
{
spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUIStyle.Green, thickness: lineThickness);
}
else if (radians > Math.PI * 2)
else if (radians >= MathHelper.TwoPi)
{
spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUIStyle.Red, thickness: lineThickness);
spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUIStyle.Green, thickness: lineThickness);
}
else
{
@@ -510,7 +510,12 @@ namespace Barotrauma.Items.Components
};
widget.MouseHeld += (deltaTime) =>
{
minRotation = GetRotationAngle(GetDrawPos());
float newMinRotation = GetRotationAngle(GetDrawPos());
AngleWrapAdjustment(minRotation, newMinRotation, ref maxRotation);
// clamp value here to keep widget movement within max range
minRotation = MathHelper.Clamp(newMinRotation, maxRotation - MathHelper.TwoPi, maxRotation);
UpdateBarrel();
MapEntity.DisableSelect = true;
};
@@ -554,7 +559,12 @@ namespace Barotrauma.Items.Components
};
widget.MouseHeld += (deltaTime) =>
{
maxRotation = GetRotationAngle(GetDrawPos());
float newMaxRotation = GetRotationAngle(GetDrawPos());
AngleWrapAdjustment(maxRotation, newMaxRotation, ref minRotation);
// clamp value here to keep widget movement within max range
maxRotation = MathHelper.Clamp(newMaxRotation, minRotation, minRotation + MathHelper.TwoPi);
UpdateBarrel();
MapEntity.DisableSelect = true;
};
@@ -580,10 +590,44 @@ namespace Barotrauma.Items.Components
void UpdateBarrel()
{
rotation = (minRotation + maxRotation) / 2;
Rotation = (minRotation + maxRotation) / 2;
}
}
private static void AngleWrapAdjustment(float currentRotation, float newRotation, ref float rangeLockedRotation)
{
if (DetectAngleWrapAround(currentRotation, newRotation))
{
// if there's a wrap-around, also wrap the other rotation limit to keep range
if (newRotation < currentRotation)
{
rangeLockedRotation -= MathHelper.TwoPi;
}
else
{
rangeLockedRotation += MathHelper.TwoPi;
}
}
}
private static bool DetectAngleWrapAround(float rotation, float newRotation)
{
float deltaRotation = MathF.Abs(rotation - newRotation);
// turret angle wraps around to 0 from -2Pi and 2Pi.
// Detect wrap-around when dragging the widgets, where usual rotation delta is small,
// so a large jump in rotation (here, an arbitrary big value in the range of 0 to 2Pi)
// is considered a wrap-around for this purpose.
// NOTE: this is not a reliable way to detect angle wrap-around in general, and is only intended for
// the angle widgets!
if (deltaRotation > MathHelper.TwoPi * 0.8f)
{
return true;
}
return false;
}
public Vector2 GetDrawPos()
{
Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);
@@ -764,7 +808,7 @@ namespace Barotrauma.Items.Components
if (projectileID == 0) { return; }
//ID ushort.MaxValue = launched without a projectile
if (projectileID == ushort.MaxValue)
if (projectileID == LaunchWithoutProjectileId)
{
Launch(null, user);
}