diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs
index 91bb79c26..736783e38 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs
@@ -66,33 +66,6 @@ namespace Barotrauma
CanBeFocused = false
};
- Point scrollButtonSize = new Point((int)(200 * GUI.Scale), (int)(30 * GUI.Scale));
-
- crewArea = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.CrewArea, guiFrame.RectTransform), "", Color.Transparent)
- {
- CanBeFocused = false
- };
- toggleCrewButton = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform)
- { AbsoluteOffset = HUDLayoutSettings.CrewArea.Location },
- "", style: "UIToggleButton");
- toggleCrewButton.OnClicked += (GUIButton btn, object userdata) =>
- {
- toggleCrewAreaOpen = !toggleCrewAreaOpen;
- foreach (GUIComponent child in btn.Children)
- {
- child.SpriteEffects = toggleCrewAreaOpen ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
- }
- return true;
- };
-
- characterListBox = new GUIListBox(new RectTransform(new Point(100, (int)(crewArea.Rect.Height - scrollButtonSize.Y * 1.6f)), crewArea.RectTransform, Anchor.CenterLeft), false, Color.Transparent, null)
- {
- //Spacing = (int)(3 * GUI.Scale),
- ScrollBarEnabled = false,
- ScrollBarVisible = false,
- CanBeFocused = false
- };
-
var characterInfo = new CharacterInfo(subElement);
characterInfos.Add(characterInfo);
foreach (XElement invElement in subElement.Elements())
@@ -103,6 +76,50 @@ namespace Barotrauma
}
}
+ var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null);
+ reportButtonFrame = new GUILayoutGroup(new RectTransform(
+ new Point((HUDLayoutSettings.CrewArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform))
+ {
+ AbsoluteSpacing = (int)(5 * GUI.Scale),
+ UserData = "reportbuttons",
+ CanBeFocused = false
+ };
+
+ //report buttons
+ foreach (Order order in reports)
+ {
+ if (!order.TargetAllCharacters || order.SymbolSprite == null) continue;
+ var btn = new GUIButton(new RectTransform(new Point(reportButtonFrame.Rect.Width), reportButtonFrame.RectTransform), style: null)
+ {
+ OnClicked = (GUIButton button, object userData) =>
+ {
+ if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
+ SetCharacterOrder(null, order, null, Character.Controlled);
+ HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull);
+ return true;
+ },
+ UserData = order,
+ ToolTip = order.Name
+ };
+
+ new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
+ {
+ Color = Color.Red * 0.8f,
+ HoverColor = Color.Red * 1.0f,
+ PressedColor = Color.Red * 0.6f,
+ UserData = "highlighted",
+ CanBeFocused = false,
+ Visible = false
+ };
+
+ var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true)
+ {
+ Color = order.Color,
+ HoverColor = Color.Lerp(order.Color, Color.White, 0.5f),
+ ToolTip = order.Name
+ };
+ }
+
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
prevUIScale = GUI.Scale;
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs
index cc9829018..e5c8ea551 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs
@@ -175,6 +175,63 @@ namespace Barotrauma.Items.Components
}
}
}
+
+ public void ApplyTo(RectTransform target)
+ {
+ if (RelativeOffset.HasValue)
+ {
+ target.RelativeOffset = RelativeOffset.Value;
+ }
+ else if (AbsoluteOffset.HasValue)
+ {
+ target.AbsoluteOffset = AbsoluteOffset.Value;
+ }
+ if (RelativeSize.HasValue)
+ {
+ target.RelativeSize = RelativeSize.Value;
+ }
+ else if (AbsoluteSize.HasValue)
+ {
+ target.NonScaledSize = AbsoluteSize.Value;
+ }
+ if (Anchor.HasValue)
+ {
+ target.Anchor = Anchor.Value;
+ }
+ if (Pivot.HasValue)
+ {
+ target.Pivot = Pivot.Value;
+ }
+ else
+ {
+ target.Pivot = RectTransform.MatchPivotToAnchor(target.Anchor);
+ }
+ target.RecalculateChildren(true, true);
+ }
+ }
+
+ public GUIFrame GuiFrame { get; protected set; }
+
+ [Serialize(false, false)]
+ public bool AllowUIOverlap
+ {
+ get;
+ set;
+ }
+
+ private ItemComponent linkToUIComponent;
+ [Serialize("", false)]
+ public string LinkUIToComponent
+ {
+ get;
+ set;
+ }
+
+ [Serialize(0, false)]
+ public int HudPriority
+ {
+ get;
+ private set;
}
private bool shouldMuffleLooping;
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs
index 6e42a2949..5feaf21da 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Turret.cs
@@ -339,11 +339,10 @@ namespace Barotrauma.Items.Components
}
}
- if (crosshairSprite != null)
- {
- crosshairSprite.Draw(spriteBatch, crosshairPos, readyToFire ? Color.White : Color.White * 0.2f, 0, (float)Math.Sqrt(cam.Zoom));
- }
- if (crosshairPointerSprite != null) crosshairPointerSprite.Draw(spriteBatch, crosshairPointerPos, 0, (float)Math.Sqrt(cam.Zoom));
+ float zoom = cam == null ? 1.0f : (float)Math.Sqrt(cam.Zoom);
+
+ crosshairSprite?.Draw(spriteBatch, crosshairPos, readyToFire ? Color.White : Color.White * 0.2f, 0, zoom);
+ crosshairPointerSprite?.Draw(spriteBatch, crosshairPointerPos, 0, zoom);
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs
index 495ba8a2f..f62bc7629 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs
@@ -289,6 +289,8 @@ namespace Barotrauma
public override void OnAttacked(Character attacker, AttackResult attackResult)
{
+ // Damage from falling etc.
+ if (Character.LastDamageSource == null) { return; }
float damage = attackResult.Damage;
if (damage <= 0) { return; }
if (attacker == null || attacker.IsDead || attacker.Removed)
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
index 4d0cc72bc..6c3d6ba8a 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
@@ -43,11 +43,80 @@ namespace Barotrauma
private set;
}
- public bool InLadders => currentPath != null && currentPath.CurrentNode != null && currentPath.CurrentNode.Ladders != null;
- public bool IsNextNodeLadder => currentPath.NextNode != null && currentPath.CurrentNode.Ladders != null;
- public bool IsNextLadderSameAsCurrent => IsNextNodeLadder && currentPath.CurrentNode.Ladders == currentPath.NextNode.Ladders;
+ ///
+ /// Returns true if the current or the next node is in ladders.
+ ///
+ public bool InLadders =>
+ currentPath != null &&
+ currentPath.CurrentNode != null && (currentPath.CurrentNode.Ladders != null ||
+ (currentPath.NextNode != null && currentPath.NextNode.Ladders != null));
- public bool InStairs => currentPath != null && currentPath.CurrentNode != null && currentPath.CurrentNode.Stairs != null;
+ ///
+ /// Returns true if the current or the next node is in stairs.
+ ///
+ public bool InStairs =>
+ currentPath != null &&
+ currentPath.CurrentNode != null && (currentPath.CurrentNode.Stairs != null ||
+ (currentPath.NextNode != null && currentPath.NextNode.Stairs != null));
+
+ public bool IsNextNodeLadder
+ {
+ get
+ {
+ if (currentPath == null) { return false; }
+ if (currentPath.NextNode == null) { return false; }
+ if (currentPath.NextNode.Ladders != null)
+ {
+ return true;
+ }
+ else
+ {
+ // Check if the node after the next node is ladder.
+ int index = currentPath.CurrentIndex + 2;
+ if (currentPath.Nodes.Count > index)
+ {
+ var node = currentPath.Nodes[index];
+ if (node == null) { return false; }
+ // Only applied if the node is close enough to the current node.
+ if (Vector2.DistanceSquared(currentPath.CurrentNode.WorldPosition, node.WorldPosition) > 100) { return false; }
+ return node.Ladders != null;
+ }
+ return false;
+ }
+ }
+ }
+
+ public bool IsNextLadderSameAsCurrent
+ {
+ get
+ {
+ if (currentPath == null) { return false; }
+ if (currentPath.CurrentNode == null) { return false; }
+ if (currentPath.NextNode == null) { return false; }
+ var currentLadder = currentPath.CurrentNode.Ladders;
+ if (currentLadder == null) { return false; }
+ var nextLadder = currentPath.NextNode.Ladders;
+ if (nextLadder != null)
+ {
+ return currentLadder == nextLadder;
+ }
+ else
+ {
+ // Check if the node after the next node is in the same ladder as the current.
+ int index = currentPath.CurrentIndex + 2;
+ if (currentPath.Nodes.Count > index)
+ {
+ var node = currentPath.Nodes[index];
+ if (node == null) { return false; }
+ // Only applied if the node is close enough to the current node.
+ if (Vector2.DistanceSquared(currentPath.CurrentNode.WorldPosition, node.WorldPosition) > 100) { return false; }
+ nextLadder = node.Ladders;
+ return nextLadder != null && nextLadder == currentLadder;
+ }
+ return false;
+ }
+ }
+ }
public IndoorsSteeringManager(ISteerable host, bool canOpenDoors, bool canBreakDoors) : base(host)
{
@@ -173,7 +242,7 @@ namespace Barotrauma
Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
bool nextLadderSamesCurrent = IsNextLadderSameAsCurrent;
- if (IsNextLadderSameAsCurrent)
+ if (nextLadderSamesCurrent)
{
//climbing ladders -> don't move horizontally
diff.X = 0.0f;
@@ -191,14 +260,14 @@ namespace Barotrauma
bool aboveFloor = heightFromFloor > 0.0f && heightFromFloor < collider.height * 1.5f;
if (aboveFloor || IsNextNodeLadder)
{
- if (!IsNextLadderSameAsCurrent)
+ if (!nextLadderSamesCurrent)
{
character.AnimController.Anim = AnimController.Animation.None;
}
currentPath.SkipToNextNode();
}
}
- else if (IsNextLadderSameAsCurrent)
+ else if (nextLadderSamesCurrent)
{
//if the current node is below the character and the next one is above (or vice versa)
//and both are on ladders, we can skip directly to the next one