(eba811de) Unstable 0.9.703.0

This commit is contained in:
Juan Pablo Arce
2020-02-04 11:54:57 -03:00
parent 15499cb704
commit 08ab6185c4
100 changed files with 2162 additions and 1520 deletions
@@ -168,10 +168,13 @@ namespace Barotrauma
public static void Draw(SpriteBatch spriteBatch, Character character, Camera cam) public static void Draw(SpriteBatch spriteBatch, Character character, Camera cam)
{ {
if (GUI.DisableHUD) return; if (GUI.DisableHUD) { return; }
character.CharacterHealth.Alignment = Alignment.Right; character.CharacterHealth.Alignment = Alignment.Right;
GUI.InfoAreaBackground.Draw(spriteBatch, Vector2.Zero); if (Screen.Selected == GameMain.GameScreen)
{
GUI.InfoAreaBackground.Draw(spriteBatch, Vector2.Zero, scale: GUI.Scale);
}
if (GameMain.GameSession?.CrewManager != null) if (GameMain.GameSession?.CrewManager != null)
{ {
@@ -41,7 +41,7 @@ namespace Barotrauma
Name, textColor: nameColor, font: GUI.LargeFont) Name, textColor: nameColor, font: GUI.LargeFont)
{ {
Padding = Vector4.Zero, Padding = Vector4.Zero,
AutoScale = true AutoScaleHorizontal = true
}; };
if (Job != null) if (Job != null)
@@ -213,10 +213,10 @@ namespace Barotrauma
} }
} }
public void DrawJobIcon(SpriteBatch spriteBatch) public void DrawJobIcon(SpriteBatch spriteBatch, Vector2? pos = null, float scale = 1.0f)
{ {
if (jobIcon == null) return; if (jobIcon == null) return;
jobIcon.Draw(spriteBatch, jobIconPos, Job.Prefab.UIColor, scale: .5f * GUI.Scale); jobIcon.Draw(spriteBatch, pos ?? jobIconPos, Job.Prefab.UIColor, scale: .5f * GUI.Scale * scale);
} }
private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None) private void DrawAttachmentSprite(SpriteBatch spriteBatch, WearableSprite attachment, Sprite head, Vector2 drawPos, float scale, float depthStep, SpriteEffects spriteEffects = SpriteEffects.None)
@@ -150,6 +150,9 @@ namespace Barotrauma
private SpriteSheet limbIndicatorOverlay; private SpriteSheet limbIndicatorOverlay;
private float limbIndicatorOverlayAnimState; private float limbIndicatorOverlayAnimState;
private SpriteSheet medUIExtra;
private float medUIExtraAnimState;
private GUIComponent draggingMed; private GUIComponent draggingMed;
private int highlightedLimbIndex = -1; private int highlightedLimbIndex = -1;
@@ -259,7 +262,7 @@ namespace Barotrauma
barSize: 1.0f, color: GUIColorSettings.HealthBarColorHigh, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical", false) barSize: 1.0f, color: GUIColorSettings.HealthBarColorHigh, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical", false)
{ {
Enabled = true, Enabled = true,
HoverCursor = CursorState.Hand, HoverCursor = CursorState.Hand,
IsHorizontal = horizontal IsHorizontal = horizontal
}; };
healthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas), healthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
@@ -271,12 +274,14 @@ namespace Barotrauma
healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.85f * 1.1f, 0.66f * 0.85f * 1.1f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI"); healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.85f * 1.1f, 0.66f * 0.85f * 1.1f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI");
var healthInterfaceLayout = new GUILayoutGroup(new RectTransform(Vector2.One / 1.1f, healthInterfaceFrame.RectTransform, anchor: Anchor.Center), true); var healthInterfaceLayout = new GUILayoutGroup(new RectTransform(Vector2.One / 1.05f, healthInterfaceFrame.RectTransform, anchor: Anchor.Center), true);
var healthWindowContainer = new GUIFrame(new RectTransform(new Vector2(0.45f, 1.0f), healthInterfaceLayout.RectTransform), style: null);
//limb selection frame //limb selection frame
healthWindow = new GUIFrame(new RectTransform(new Vector2(0.45f, 1.0f), healthInterfaceLayout.RectTransform), style: null); healthWindow = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), healthWindowContainer.RectTransform, Anchor.CenterRight, Pivot.CenterRight), style: "GUIFrameListBox");
var healthWindowVerticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, healthWindow.RectTransform, Anchor.Center)); var healthWindowVerticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.95f, healthWindow.RectTransform, Anchor.Center));
var paddedHealthWindow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.95f), healthWindowVerticalLayout.RectTransform), true) var paddedHealthWindow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.95f), healthWindowVerticalLayout.RectTransform), true)
{ {
@@ -301,9 +306,34 @@ namespace Barotrauma
CanBeFocused = false CanBeFocused = false
}; };
GUILayoutGroup selectedLimbLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), paddedHealthWindow.RectTransform)); var rightSide = new GUIFrame(new RectTransform(new Vector2(0.4f, 1.0f), paddedHealthWindow.RectTransform), style: null);
new GUICustomComponent(new RectTransform(new Vector2(1.0f, 0.3f), rightSide.RectTransform, Anchor.BottomRight, Pivot.BottomRight),
(sb, component) =>
{
if (medUIExtra == null) { return; }
float overlayScale = Math.Min(
component.Rect.Width / (float)medUIExtra.FrameSize.X,
component.Rect.Height / (float)medUIExtra.FrameSize.Y);
int frame = (int)medUIExtraAnimState;
medUIExtra.Draw(sb, frame, component.Rect.Center.ToVector2(), Color.Gray, origin: medUIExtra.FrameSize.ToVector2() / 2, rotate: 0.0f,
scale: Vector2.One * overlayScale);
},
(dt, component) =>
{
medUIExtraAnimState += dt * 10.0f;
while (medUIExtraAnimState >= 16.0f)
{
medUIExtraAnimState -= 16.0f;
}
});
GUILayoutGroup selectedLimbLayout = new GUILayoutGroup(new RectTransform(Vector2.One, rightSide.RectTransform));
selectedLimbText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.08f), selectedLimbLayout.RectTransform), "", font: GUI.LargeFont); selectedLimbText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.08f), selectedLimbLayout.RectTransform), "", font: GUI.LargeFont);
selectedLimbText.AutoScaleHorizontal = true;
afflictionIconContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.92f), selectedLimbLayout.RectTransform), style: null); afflictionIconContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.92f), selectedLimbLayout.RectTransform), style: null);
afflictionIconContainer.KeepSpaceForScrollBar = true; afflictionIconContainer.KeepSpaceForScrollBar = true;
@@ -327,9 +357,21 @@ namespace Barotrauma
afflictionInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.55f, 1.0f), healthInterfaceLayout.RectTransform), style: null); afflictionInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.55f, 1.0f), healthInterfaceLayout.RectTransform), style: null);
var paddedInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), afflictionInfoFrame.RectTransform, Anchor.Center), style: null); var paddedInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), afflictionInfoFrame.RectTransform, Anchor.Center), style: null);
var infoLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedInfoFrame.RectTransform)); var infoLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedInfoFrame.RectTransform))
{
Stretch = true,
RelativeSpacing = 0.03f
};
var nameContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), infoLayout.RectTransform) { MinSize = new Point(0, 20) }, isHorizontal: true) var textContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), infoLayout.RectTransform), style: "GUIFrameListBox");
var textLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1.0f), textContainer.RectTransform, Anchor.Center, Pivot.Center))
{
Stretch = true,
RelativeSpacing = 0.03f
};
var nameContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), textLayout.RectTransform) { MinSize = new Point(0, 20) }, isHorizontal: true)
{ {
Stretch = true Stretch = true
}; };
@@ -338,25 +380,29 @@ namespace Barotrauma
onDraw: (spriteBatch, component) => onDraw: (spriteBatch, component) =>
{ {
character.Info.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), component.Rect.Width); character.Info.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), component.Rect.Width);
character.Info.DrawJobIcon(spriteBatch, new Vector2(component.Rect.Right + component.Rect.Width, (float)component.Rect.Top + component.Rect.Height * 0.75f), 0.75f);
}); });
characterName = new GUITextBlock(new RectTransform(new Vector2(0.85f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.LargeFont) characterName = new GUITextBlock(new RectTransform(new Vector2(0.85f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.BottomLeft, font: GUI.SubHeadingFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), textLayout.RectTransform), style: "HorizontalLine");
afflictionInfoContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), infoLayout.RectTransform, Anchor.TopLeft)); afflictionInfoContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), textLayout.RectTransform, Anchor.TopLeft), style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), infoLayout.RectTransform, Anchor.TopLeft), TextManager.Get("SuitableTreatments"), textAlignment: Alignment.TopLeft); new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), textLayout.RectTransform), style: "HorizontalLine");
treatmentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), infoLayout.RectTransform), true) new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), textLayout.RectTransform, Anchor.TopLeft), TextManager.Get("SuitableTreatments"), textAlignment: Alignment.TopLeft);
treatmentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), textLayout.RectTransform), true)
{ {
Stretch = true Stretch = false
}; };
recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(0.9f, 1.0f), treatmentLayout.RectTransform, Anchor.TopLeft), isHorizontal: true, style: null) recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(0.9f, 1.0f), treatmentLayout.RectTransform, Anchor.Center, Pivot.Center), isHorizontal: true, style: null)
{ {
KeepSpaceForScrollBar = true KeepSpaceForScrollBar = false
}; };
lowSkillIndicator = new GUIImage(new RectTransform(new Vector2(0.1f, 1.0f), treatmentLayout.RectTransform, Anchor.TopLeft, Pivot.Center), lowSkillIndicator = new GUIImage(new RectTransform(new Vector2(0.1f, 1.0f), treatmentLayout.RectTransform, Anchor.TopLeft, Pivot.Center),
@@ -370,6 +416,8 @@ namespace Barotrauma
}; };
lowSkillIndicator.RectTransform.MaxSize = new Point(lowSkillIndicator.Rect.Height); lowSkillIndicator.RectTransform.MaxSize = new Point(lowSkillIndicator.Rect.Height);
var tempFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), textLayout.RectTransform), style: null);
cprLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), infoLayout.RectTransform), true) cprLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), infoLayout.RectTransform), true)
{ {
Stretch = true Stretch = true
@@ -443,8 +491,12 @@ namespace Barotrauma
switch (subElement.Name.ToString().ToLowerInvariant()) switch (subElement.Name.ToString().ToLowerInvariant())
{ {
case "sprite": case "sprite":
case "meduisilhouette":
limbIndicatorOverlay = new SpriteSheet(subElement); limbIndicatorOverlay = new SpriteSheet(subElement);
break; break;
case "meduiextra":
medUIExtra = new SpriteSheet(subElement);
break;
} }
} }
} }
@@ -1062,9 +1114,9 @@ namespace Barotrauma
var button = new GUIButton(new RectTransform(new Vector2(1.0f, 0.9f), child.RectTransform), style: null) var button = new GUIButton(new RectTransform(new Vector2(1.0f, 0.9f), child.RectTransform), style: null)
{ {
Color = Color.Gray.Multiply(0.1f), Color = Color.Gray.Multiply(0.1f).Opaque(),
HoverColor = Color.Gray.Multiply(0.4f), HoverColor = Color.Gray.Multiply(0.4f).Opaque(),
SelectedColor = Color.Gray.Multiply(0.25f), SelectedColor = Color.Gray.Multiply(0.25f).Opaque(),
PressedColor = Color.Black, PressedColor = Color.Black,
UserData = "selectaffliction", UserData = "selectaffliction",
OnClicked = SelectAffliction OnClicked = SelectAffliction
@@ -1100,22 +1152,27 @@ namespace Barotrauma
List<KeyValuePair<string, float>> treatmentSuitabilities = treatmentSuitability.OrderByDescending(t => t.Value).ToList(); List<KeyValuePair<string, float>> treatmentSuitabilities = treatmentSuitability.OrderByDescending(t => t.Value).ToList();
int count = 0;
foreach (KeyValuePair<string, float> treatment in treatmentSuitabilities) foreach (KeyValuePair<string, float> treatment in treatmentSuitabilities)
{ {
count++;
if (count > 5) { break; }
ItemPrefab item = MapEntityPrefab.Find(name: null, identifier: treatment.Key, showErrorMessages: false) as ItemPrefab; ItemPrefab item = MapEntityPrefab.Find(name: null, identifier: treatment.Key, showErrorMessages: false) as ItemPrefab;
if (item == null) continue; if (item == null) continue;
var itemSlot = new GUIFrame(new RectTransform(new Vector2(0.25f, 1.0f), recommendedTreatmentContainer.Content.RectTransform, Anchor.TopLeft), var itemSlot = new GUIFrame(new RectTransform(new Vector2(1.0f / 7.0f, 1.0f), recommendedTreatmentContainer.Content.RectTransform, Anchor.TopLeft),
style: "InnerGlow") style: null)
{ {
UserData = item UserData = item
}; };
itemSlot.Color = ToolBox.GradientLerp(treatment.Value, GUI.Style.Red, GUI.Style.Orange, GUI.Style.Green);
itemSlot.SelectedColor = itemSlot.HoverColor = itemSlot.Color;
var innerFrame = new GUIFrame(new RectTransform(Vector2.One, itemSlot.RectTransform, Anchor.Center, Pivot.Center, scaleBasis: ScaleBasis.Smallest), style: "GUIFrameListBox")
{
CanBeFocused = false
};
Sprite itemSprite = item.InventoryIcon ?? item.sprite; Sprite itemSprite = item.InventoryIcon ?? item.sprite;
Color itemColor = itemSprite == item.sprite ? item.SpriteColor : item.InventoryIconColor; Color itemColor = itemSprite == item.sprite ? item.SpriteColor : item.InventoryIconColor;
var itemIcon = new GUIImage(new RectTransform(new Vector2(0.8f, 0.8f), itemSlot.RectTransform, Anchor.Center), var itemIcon = new GUIImage(new RectTransform(new Vector2(0.8f, 0.8f), innerFrame.RectTransform, Anchor.Center),
itemSprite, scaleToFit: true) itemSprite, scaleToFit: true)
{ {
CanBeFocused = false, CanBeFocused = false,
@@ -1242,11 +1299,11 @@ namespace Barotrauma
private void UpdateHeartrate(float deltaTime, GUICustomComponent component) private void UpdateHeartrate(float deltaTime, GUICustomComponent component)
{ {
heartbeatTimer -= deltaTime; heartbeatTimer -= deltaTime * 0.75f;
if (heartbeatTimer <= 0.0f) if (heartbeatTimer <= 0.0f)
{ {
heartbeatTimer = 0.5f; while (heartbeatTimer <= 0.0f) { heartbeatTimer += 0.5f; }
IEnumerable<HeartratePosition> newPositions; IEnumerable<HeartratePosition> newPositions;
if (Character == null || Character.IsDead || Character.IsUnconscious) if (Character == null || Character.IsDead || Character.IsUnconscious)
@@ -1278,7 +1335,7 @@ namespace Barotrauma
} }
} }
currentHeartrateTime += deltaTime; currentHeartrateTime += deltaTime * 0.75f;
while (currentHeartrateTime >= 1.0f) while (currentHeartrateTime >= 1.0f)
{ {
currentHeartrateTime -= 1.0f; currentHeartrateTime -= 1.0f;
@@ -1287,16 +1344,20 @@ namespace Barotrauma
private void DrawHeartrate(SpriteBatch spriteBatch, GUICustomComponent component) private void DrawHeartrate(SpriteBatch spriteBatch, GUICustomComponent component)
{ {
GUI.DrawRectangle(spriteBatch, component.Rect, Color.Black, true); Rectangle targetRect = component.Parent.Rect;
targetRect.Location += new Point(6, 6);
targetRect.Size -= new Point(12, 12);
//GUI.DrawRectangle(spriteBatch, targetRect, Color.Black, true);
bool first = true; bool first = true;
Vector2 prevPos = Vector2.Zero; Vector2 prevPos = Vector2.Zero;
foreach (var heartratePosition in heartratePositions.OrderBy(hp => hp.Time)) foreach (var heartratePosition in heartratePositions.OrderBy(hp => hp.Time))
{ {
Vector2 pos = new Vector2(heartratePosition.Time, -heartratePosition.Height * 0.5f + 0.5f) * component.Rect.Size.ToVector2() + component.Rect.Location.ToVector2(); Vector2 pos = new Vector2(heartratePosition.Time, -heartratePosition.Height * 0.5f + 0.5f) * targetRect.Size.ToVector2() + targetRect.Location.ToVector2();
if (pos.X < component.Rect.Left + 1) { pos.X = component.Rect.Left + 1; } if (pos.X < targetRect.Left + 1) { pos.X = targetRect.Left + 1; }
if (pos.X > component.Rect.Right - 1) { pos.X = component.Rect.Right - 1; } if (pos.X > targetRect.Right - 1) { pos.X = targetRect.Right - 1; }
if (first) if (first)
{ {
@@ -1317,17 +1378,17 @@ namespace Barotrauma
Rectangle sourceRect = heartrateFade.Bounds; Rectangle sourceRect = heartrateFade.Bounds;
Rectangle destinationRectangle = new Rectangle(); Rectangle destinationRectangle = new Rectangle();
destinationRectangle.Location = new Point((int)(currentHeartrateTime * component.Rect.Width) + component.Rect.Left - component.Rect.Height, component.Rect.Top); destinationRectangle.Location = new Point((int)(currentHeartrateTime * targetRect.Width) + targetRect.Left - targetRect.Height, targetRect.Top);
destinationRectangle.Size = new Point((int)(component.Rect.Height * ((float)sourceRect.Width / (float)sourceRect.Height)), component.Rect.Height); destinationRectangle.Size = new Point((int)(targetRect.Height * ((float)sourceRect.Width / (float)sourceRect.Height)), targetRect.Height);
if (destinationRectangle.Left < component.Rect.Left) if (destinationRectangle.Left < targetRect.Left)
{ {
Rectangle destinationRectangle2 = new Rectangle(); Rectangle destinationRectangle2 = new Rectangle();
destinationRectangle2.Location = new Point(component.Rect.Right - (component.Rect.Left - destinationRectangle.Left), component.Rect.Top); destinationRectangle2.Location = new Point(targetRect.Right - (targetRect.Left - destinationRectangle.Left), targetRect.Top);
destinationRectangle2.Size = new Point(component.Rect.Right - destinationRectangle2.Left, component.Rect.Height); destinationRectangle2.Size = new Point(targetRect.Right - destinationRectangle2.Left, targetRect.Height);
int originalWidth = sourceRect.Width; int originalWidth = sourceRect.Width;
sourceRect.Width = (int)(sourceRect.Width * ((float)(destinationRectangle.Right - component.Rect.Left) / (float)component.Rect.Height)); sourceRect.Width = (int)(sourceRect.Width * ((float)(destinationRectangle.Right - targetRect.Left) / (float)targetRect.Height));
sourceRect.X += originalWidth - sourceRect.Width; sourceRect.X += originalWidth - sourceRect.Width;
Rectangle sourceRect2 = heartrateFade.Bounds; Rectangle sourceRect2 = heartrateFade.Bounds;
@@ -1335,9 +1396,9 @@ namespace Barotrauma
spriteBatch.Draw(heartrateFade, destinationRectangle2, sourceRect2, Color.White); spriteBatch.Draw(heartrateFade, destinationRectangle2, sourceRect2, Color.White);
originalWidth = destinationRectangle.Width; originalWidth = destinationRectangle.Width;
int newWidth = destinationRectangle.Right - component.Rect.Left; int newWidth = destinationRectangle.Right - targetRect.Left;
destinationRectangle.Size = new Point(newWidth, component.Rect.Height); destinationRectangle.Size = new Point(newWidth, targetRect.Height);
destinationRectangle.X += originalWidth - newWidth; destinationRectangle.X += originalWidth - newWidth;
GUI.DrawRectangle(spriteBatch, new Rectangle(destinationRectangle.Right, destinationRectangle.Top, GUI.DrawRectangle(spriteBatch, new Rectangle(destinationRectangle.Right, destinationRectangle.Top,
@@ -1346,9 +1407,9 @@ namespace Barotrauma
else else
{ {
GUI.DrawRectangle(spriteBatch, new Rectangle(destinationRectangle.Right, destinationRectangle.Top, GUI.DrawRectangle(spriteBatch, new Rectangle(destinationRectangle.Right, destinationRectangle.Top,
component.Rect.Right - destinationRectangle.Right, destinationRectangle.Height), Color.Black, true); targetRect.Right - destinationRectangle.Right, destinationRectangle.Height), Color.Black, true);
GUI.DrawRectangle(spriteBatch, new Rectangle(component.Rect.Left, destinationRectangle.Top, GUI.DrawRectangle(spriteBatch, new Rectangle(targetRect.Left, destinationRectangle.Top,
destinationRectangle.Left - component.Rect.Left, destinationRectangle.Height), Color.Black, true); destinationRectangle.Left - targetRect.Left, destinationRectangle.Height), Color.Black, true);
} }
spriteBatch.Draw(heartrateFade, destinationRectangle, sourceRect, Color.White); spriteBatch.Draw(heartrateFade, destinationRectangle, sourceRect, Color.White);
@@ -1515,45 +1576,43 @@ namespace Barotrauma
float damageLerp = limbHealth.TotalDamage > 0.0f ? MathHelper.Lerp(0.2f, 1.0f, limbHealth.TotalDamage / 100.0f) : 0.0f; float damageLerp = limbHealth.TotalDamage > 0.0f ? MathHelper.Lerp(0.2f, 1.0f, limbHealth.TotalDamage / 100.0f) : 0.0f;
var tempAfflictions = limbHealth.Afflictions.ToList(); var tempAfflictions = GetMatchingAfflictions(limbHealth, a => true);
foreach (var a in afflictions)
{
Limb indicatorLimb = Character.AnimController.GetLimb(a.Prefab.IndicatorLimb);
if (indicatorLimb != null && indicatorLimb.HealthIndex == i)
{
tempAfflictions.Add(a);
}
}
float negativeEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff).Sum(a => a.Strength); float negativeEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff && a.Strength >= a.Prefab.ShowIconThreshold).Sum(a => a.Strength);
float positiveEffect = tempAfflictions.Where(a => a.Prefab.IsBuff).Sum(a => a.Strength); //float negativeMaxEffect = tempAfflictions.Where(a => !a.Prefab.IsBuff).Sum(a => a.Prefab.MaxStrength);
float positiveEffect = tempAfflictions.Where(a => a.Prefab.IsBuff && a.Strength >= a.Prefab.ShowIconThreshold).Sum(a => a.Strength * 0.2f);
//float positiveMaxEffect = tempAfflictions.Where(a => a.Prefab.IsBuff).Sum(a => a.Prefab.MaxStrength);
float midPoint = (float)limbEffectiveArea.Center.Y / (float)limbHealth.IndicatorSprite.Texture.Height; float midPoint = (float)limbEffectiveArea.Center.Y / (float)limbHealth.IndicatorSprite.Texture.Height;
float fadeDist = 0.6f * (float)limbEffectiveArea.Height / (float)limbHealth.IndicatorSprite.Texture.Height; float fadeDist = 0.6f * (float)limbEffectiveArea.Height / (float)limbHealth.IndicatorSprite.Texture.Height;
if (negativeEffect > 0.0f && negativeEffect < 5.0f) { negativeEffect = 5.0f; }
if (positiveEffect > 0.0f && positiveEffect < 5.0f) { positiveEffect = 5.0f; }
Color positiveColor = Color.Lerp(Color.Orange, Color.Lime, Math.Min(positiveEffect / 15.0f, 1.0f));
Color negativeColor = Color.Lerp(Color.Orange, Color.Red, Math.Min(negativeEffect / 15.0f, 1.0f));
Color color1 = Color.Orange; Color color1 = Color.Orange;
Color color2 = Color.Orange; Color color2 = Color.Orange;
if (positiveEffect > 0.0f && negativeEffect > 0.0f) if (negativeEffect+positiveEffect > 0.0f)
{ {
color1 = Color.Lime; if (negativeEffect >= positiveEffect)
color2 = Color.Red; {
} color1 = Color.Lerp(positiveColor, negativeColor, (negativeEffect - positiveEffect) / negativeEffect);
else if (positiveEffect > 0.0f) color2 = negativeColor;
{ }
color1 = Color.Lime; else
color2 = Color.Lime; {
} color1 = positiveColor;
else if (negativeEffect > 0.0f) color2 = Color.Lerp(negativeColor, positiveColor, (positiveEffect - negativeEffect) / positiveEffect);
{ }
color1 = Color.Red;
color2 = Color.Red;
} }
if (Character.IsDead) if (Character.IsDead)
{ {
color1 = Color.Lerp(color1, Color.Black, 0.5f); color1 = Color.Lerp(color1, Color.Black, 0.75f);
color2 = Color.Lerp(color2, Color.Black, 0.5f); color2 = Color.Lerp(color2, Color.Black, 0.75f);
} }
if (((i == highlightedLimbIndex || i == selectedLimbIndex) && allowHighlight) || highlightAll) if (((i == highlightedLimbIndex || i == selectedLimbIndex) && allowHighlight) || highlightAll)
{ {
@@ -1610,22 +1669,20 @@ namespace Barotrauma
spriteBatch.End(); spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, blendState: BlendState.NonPremultiplied, rasterizerState: GameMain.ScissorTestEnable); spriteBatch.Begin(SpriteSortMode.Deferred, blendState: BlendState.NonPremultiplied, rasterizerState: GameMain.ScissorTestEnable);
/*i = 0; i = 0;
foreach (LimbHealth limbHealth in limbHealths) foreach (LimbHealth limbHealth in limbHealths)
{ {
if (limbHealth.IndicatorSprite == null) continue; if (limbHealth.IndicatorSprite == null) continue;
Rectangle highlightArea = GetLimbHighlightArea(limbHealth, drawArea); Rectangle highlightArea = GetLimbHighlightArea(limbHealth, drawArea);
var slot = GUI.Style.GetComponentStyle("AfflictionIconSlot");
float scale = Math.Min(drawArea.Width / (float)limbHealth.IndicatorSprite.SourceRect.Width, drawArea.Height / (float)limbHealth.IndicatorSprite.SourceRect.Height); float scale = Math.Min(drawArea.Width / (float)limbHealth.IndicatorSprite.SourceRect.Width, drawArea.Height / (float)limbHealth.IndicatorSprite.SourceRect.Height);
float iconScale = 0.3f * scale; float iconScale = 0.3f * scale;
Vector2 iconPos = highlightArea.Center.ToVector2(); Vector2 iconPos = highlightArea.Center.ToVector2();
foreach (Affliction affliction in limbHealth.Afflictions) foreach (Affliction affliction in limbHealth.Afflictions)
{ {
DrawLimbAfflictionIcon(spriteBatch, affliction, slot, iconScale, ref iconPos); DrawLimbAfflictionIcon(spriteBatch, affliction, iconScale, ref iconPos);
} }
foreach (Affliction affliction in afflictions) foreach (Affliction affliction in afflictions)
@@ -1633,11 +1690,11 @@ namespace Barotrauma
Limb indicatorLimb = Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb); Limb indicatorLimb = Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb);
if (indicatorLimb != null && indicatorLimb.HealthIndex == i) if (indicatorLimb != null && indicatorLimb.HealthIndex == i)
{ {
DrawLimbAfflictionIcon(spriteBatch, affliction, slot, iconScale, ref iconPos); DrawLimbAfflictionIcon(spriteBatch, affliction, iconScale, ref iconPos);
} }
} }
i++; i++;
}*/ }
if (draggingMed != null) if (draggingMed != null)
{ {
@@ -1647,7 +1704,7 @@ namespace Barotrauma
} }
} }
private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, GUIComponentStyle slotStyle, float iconScale, ref Vector2 iconPos) private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, float iconScale, ref Vector2 iconPos)
{ {
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) return; if (affliction.Strength < affliction.Prefab.ShowIconThreshold) return;
Vector2 iconSize = (affliction.Prefab.Icon.size * iconScale); Vector2 iconSize = (affliction.Prefab.Icon.size * iconScale);
@@ -1656,10 +1713,6 @@ namespace Barotrauma
float alpha = MathHelper.Lerp(0.3f, 1.0f, float alpha = MathHelper.Lerp(0.3f, 1.0f,
(affliction.Strength - affliction.Prefab.ShowIconThreshold) / Math.Min(affliction.Prefab.MaxStrength - affliction.Prefab.ShowIconThreshold, 10.0f)); (affliction.Strength - affliction.Prefab.ShowIconThreshold) / Math.Min(affliction.Prefab.MaxStrength - affliction.Prefab.ShowIconThreshold, 10.0f));
slotStyle.Sprites[GUIComponent.ComponentState.None][0].Draw(
spriteBatch,
new Rectangle((iconPos - iconSize / 2.0f).ToPoint(), iconSize.ToPoint()),
slotStyle.Color * alpha);
affliction.Prefab.Icon.Draw(spriteBatch, iconPos - iconSize / 2.0f, GetAfflictionIconColor(affliction.Prefab, affliction) * alpha, 0, iconScale); affliction.Prefab.Icon.Draw(spriteBatch, iconPos - iconSize / 2.0f, GetAfflictionIconColor(affliction.Prefab, affliction) * alpha, 0, iconScale);
iconPos += new Vector2(10.0f, 20.0f) * iconScale; iconPos += new Vector2(10.0f, 20.0f) * iconScale;
} }
@@ -11,5 +11,10 @@ namespace Barotrauma.Extensions
new Color(color.R, color.G, color.B, (byte)(color.A * value)) : new Color(color.R, color.G, color.B, (byte)(color.A * value)) :
new Color((byte)(color.R * value), (byte)(color.G * value), (byte)(color.B * value), (byte)(color.A * value)); new Color((byte)(color.R * value), (byte)(color.G * value), (byte)(color.B * value), (byte)(color.A * value));
} }
public static Color Opaque(this Color color)
{
return new Color(color.R, color.G, color.B, (byte)255);
}
} }
} }
@@ -198,10 +198,6 @@ namespace Barotrauma
this.texDims = texDims; this.texDims = texDims;
this.baseChar = baseChar; this.baseChar = baseChar;
lock (mutex)
{
face.SetPixelSizes(0, size);
}
textures.ForEach(t => t.Dispose()); textures.ForEach(t => t.Dispose());
textures.Clear(); textures.Clear();
texCoords.Clear(); texCoords.Clear();
@@ -223,17 +219,15 @@ namespace Barotrauma
lock (mutex) lock (mutex)
{ {
face.SetPixelSizes(0, size);
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal); face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
baseHeight = face.Glyph.Metrics.Height.ToInt32(); baseHeight = face.Glyph.Metrics.Height.ToInt32();
}
//lineHeight = baseHeight; for (int i = 0; i < charRanges.Length; i += 2)
for (int i = 0; i < charRanges.Length; i += 2)
{
uint start = charRanges[i];
uint end = charRanges[i + 1];
for (uint j = start; j <= end; j++)
{ {
lock (mutex) uint start = charRanges[i];
uint end = charRanges[i + 1];
for (uint j = start; j <= end; j++)
{ {
uint glyphIndex = face.GetCharIndex(j); uint glyphIndex = face.GetCharIndex(j);
if (glyphIndex == 0) continue; if (glyphIndex == 0) continue;
@@ -307,107 +301,118 @@ namespace Barotrauma
currentCoords.X += glyphWidth + 2; currentCoords.X += glyphWidth + 2;
} }
CrossThread.RequestExecutionOnMainThread(() =>
{
textures[texIndex].SetData<uint>(pixelBuffer);
});
} }
CrossThread.RequestExecutionOnMainThread(() =>
{
textures[texIndex].SetData<uint>(pixelBuffer);
});
} }
} }
public void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54) public void DynamicRenderAtlas(GraphicsDevice gd, uint character, int texDims = 1024, uint baseChar = 0x54)
{ {
if (textures.Count == 0) if (System.Threading.Thread.CurrentThread != GameMain.MainThread)
{ {
this.texDims = texDims;
this.baseChar = baseChar;
lock (mutex) { face.SetPixelSizes(0, size); }
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
baseHeight = face.Glyph.Metrics.Height.ToInt32();
CrossThread.RequestExecutionOnMainThread(() => CrossThread.RequestExecutionOnMainThread(() =>
{ {
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color)); DynamicRenderAtlas(gd, character, texDims, baseChar);
}); });
}
uint glyphIndex = face.GetCharIndex(character);
if (glyphIndex == 0) { return; }
lock (mutex) { face.SetPixelSizes(0, size); }
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
{
if (face.Glyph.Metrics.HorizontalAdvance > 0)
{
//glyph is empty, but char still applies advance
GlyphData blankData = new GlyphData();
blankData.advance = (float)face.Glyph.Metrics.HorizontalAdvance;
blankData.texIndex = -1; //indicates no texture because the glyph is empty
texCoords.Add(character, blankData);
}
return; return;
} }
//stacktrace doesn't really work that well when RenderGlyph throws an exception byte[] bitmap;
face.Glyph.RenderGlyph(RenderMode.Normal); int glyphWidth; int glyphHeight;
byte[] bitmap = face.Glyph.Bitmap.BufferData; Fixed26Dot6 horizontalAdvance;
int glyphWidth = face.Glyph.Bitmap.Width; Vector2 drawOffset;
int glyphHeight = bitmap.Length / glyphWidth;
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1) lock (mutex)
{ {
throw new Exception(filename + ", " + size.ToString() + ", " + (char)character + "; Glyph dimensions exceed texture atlas dimensions"); if (texCoords.ContainsKey(character)) { return; }
} if (textures.Count == 0)
currentDynamicAtlasNextY = Math.Max(currentDynamicAtlasNextY, glyphHeight + 2);
if (currentDynamicAtlasCoords.X + glyphWidth + 2 > texDims - 1)
{
currentDynamicAtlasCoords.X = 0;
currentDynamicAtlasCoords.Y += currentDynamicAtlasNextY;
currentDynamicAtlasNextY = 0;
}
//no more room in current texture atlas, create a new one
if (currentDynamicAtlasCoords.Y + glyphHeight + 2 > texDims - 1)
{
currentDynamicAtlasCoords.X = 0;
currentDynamicAtlasCoords.Y = 0;
currentDynamicAtlasNextY = 0;
CrossThread.RequestExecutionOnMainThread(() =>
{ {
this.texDims = texDims;
this.baseChar = baseChar;
face.SetPixelSizes(0, size);
face.LoadGlyph(face.GetCharIndex(baseChar), LoadFlags.Default, LoadTarget.Normal);
baseHeight = face.Glyph.Metrics.Height.ToInt32();
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color)); textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
});
currentDynamicPixelBuffer = null;
}
GlyphData newData = new GlyphData
{
advance = (float)face.Glyph.Metrics.HorizontalAdvance,
texIndex = textures.Count - 1,
texCoords = new Rectangle((int)currentDynamicAtlasCoords.X, (int)currentDynamicAtlasCoords.Y, glyphWidth, glyphHeight),
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop)
};
texCoords.Add(character, newData);
if (currentDynamicPixelBuffer == null)
{
currentDynamicPixelBuffer = new uint[texDims * texDims];
textures[newData.texIndex].GetData<uint>(currentDynamicPixelBuffer, 0, texDims * texDims);
}
for (int y = 0; y < glyphHeight; y++)
{
for (int x = 0; x < glyphWidth; x++)
{
byte byteColor = bitmap[x + y * glyphWidth];
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | 0x00ffffff);
} }
}
CrossThread.RequestExecutionOnMainThread(() =>
{
textures[newData.texIndex].SetData<uint>(currentDynamicPixelBuffer);
});
currentDynamicAtlasCoords.X += glyphWidth + 2; uint glyphIndex = face.GetCharIndex(character);
if (glyphIndex == 0) { return; }
face.SetPixelSizes(0, size);
face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
if (face.Glyph.Metrics.Width == 0 || face.Glyph.Metrics.Height == 0)
{
if (face.Glyph.Metrics.HorizontalAdvance > 0)
{
//glyph is empty, but char still applies advance
GlyphData blankData = new GlyphData();
blankData.advance = (float)face.Glyph.Metrics.HorizontalAdvance;
blankData.texIndex = -1; //indicates no texture because the glyph is empty
texCoords.Add(character, blankData);
}
return;
}
//stacktrace doesn't really work that well when RenderGlyph throws an exception
face.Glyph.RenderGlyph(RenderMode.Normal);
bitmap = (byte[])face.Glyph.Bitmap.BufferData.Clone();
glyphWidth = face.Glyph.Bitmap.Width;
glyphHeight = bitmap.Length / glyphWidth;
horizontalAdvance = face.Glyph.Metrics.HorizontalAdvance;
drawOffset = new Vector2(face.Glyph.BitmapLeft, baseHeight * 14 / 10 - face.Glyph.BitmapTop);
if (glyphWidth > texDims - 1 || glyphHeight > texDims - 1)
{
throw new Exception(filename + ", " + size.ToString() + ", " + (char)character + "; Glyph dimensions exceed texture atlas dimensions");
}
currentDynamicAtlasNextY = Math.Max(currentDynamicAtlasNextY, glyphHeight + 2);
if (currentDynamicAtlasCoords.X + glyphWidth + 2 > texDims - 1)
{
currentDynamicAtlasCoords.X = 0;
currentDynamicAtlasCoords.Y += currentDynamicAtlasNextY;
currentDynamicAtlasNextY = 0;
}
//no more room in current texture atlas, create a new one
if (currentDynamicAtlasCoords.Y + glyphHeight + 2 > texDims - 1)
{
currentDynamicAtlasCoords.X = 0;
currentDynamicAtlasCoords.Y = 0;
currentDynamicAtlasNextY = 0;
textures.Add(new Texture2D(gd, texDims, texDims, false, SurfaceFormat.Color));
currentDynamicPixelBuffer = null;
}
GlyphData newData = new GlyphData
{
advance = (float)horizontalAdvance,
texIndex = textures.Count - 1,
texCoords = new Rectangle((int)currentDynamicAtlasCoords.X, (int)currentDynamicAtlasCoords.Y, glyphWidth, glyphHeight),
drawOffset = drawOffset
};
texCoords.Add(character, newData);
if (currentDynamicPixelBuffer == null)
{
currentDynamicPixelBuffer = new uint[texDims * texDims];
textures[newData.texIndex].GetData<uint>(currentDynamicPixelBuffer, 0, texDims * texDims);
}
for (int y = 0; y < glyphHeight; y++)
{
for (int x = 0; x < glyphWidth; x++)
{
byte byteColor = bitmap[x + y * glyphWidth];
currentDynamicPixelBuffer[((int)currentDynamicAtlasCoords.X + x) + ((int)currentDynamicAtlasCoords.Y + y) * texDims] = (uint)(byteColor << 24 | 0x00ffffff);
}
}
textures[newData.texIndex].SetData<uint>(currentDynamicPixelBuffer);
currentDynamicAtlasCoords.X += glyphWidth + 2;
}
} }
public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth) public void DrawString(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth)
@@ -429,7 +434,7 @@ namespace Barotrauma
} }
uint charIndex = text[i]; uint charIndex = text[i];
if (DynamicLoading && !texCoords.ContainsKey(charIndex)) if (DynamicLoading)
{ {
DynamicRenderAtlas(graphicsDevice, charIndex); DynamicRenderAtlas(graphicsDevice, charIndex);
} }
@@ -470,7 +475,7 @@ namespace Barotrauma
} }
uint charIndex = text[i]; uint charIndex = text[i];
if (DynamicLoading && !texCoords.ContainsKey(charIndex)) if (DynamicLoading)
{ {
DynamicRenderAtlas(graphicsDevice, charIndex); DynamicRenderAtlas(graphicsDevice, charIndex);
} }
@@ -12,7 +12,8 @@ namespace Barotrauma
{ {
class ChatBox class ChatBox
{ {
private static Sprite radioIcon; public const string RadioChatString = "r; ";
private GUIListBox chatBox; private GUIListBox chatBox;
private Point screenResolution; private Point screenResolution;
@@ -26,8 +27,8 @@ namespace Barotrauma
get { return _toggleOpen; } get { return _toggleOpen; }
set set
{ {
if (_toggleOpen == value) { return; }
_toggleOpen = GameMain.Config.ChatOpen = value; _toggleOpen = GameMain.Config.ChatOpen = value;
if (value) hideableElements.Visible = true;
foreach (GUIComponent child in ToggleButton.Children) foreach (GUIComponent child in ToggleButton.Children)
{ {
child.SpriteEffects = _toggleOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None; child.SpriteEffects = _toggleOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
@@ -65,11 +66,6 @@ namespace Barotrauma
public ChatBox(GUIComponent parent, bool isSinglePlayer) public ChatBox(GUIComponent parent, bool isSinglePlayer)
{ {
this.IsSinglePlayer = isSinglePlayer; this.IsSinglePlayer = isSinglePlayer;
if (radioIcon == null)
{
radioIcon = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(527, 952, 38, 52), null);
radioIcon.Origin = radioIcon.size / 2;
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
@@ -105,7 +101,7 @@ namespace Barotrauma
//gui.Text = ""; //gui.Text = "";
}; };
var chatSendButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.7f), InputBox.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonToggleRight"); var chatSendButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.7f), InputBox.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonToggleRight");
chatSendButton.OnClicked += (GUIButton btn, object userdata) => chatSendButton.OnClicked += (GUIButton btn, object userdata) =>
{ {
InputBox.OnEnterPressed(InputBox, InputBox.Text); InputBox.OnEnterPressed(InputBox, InputBox.Text);
@@ -339,7 +335,7 @@ namespace Barotrauma
showNewMessagesButton.Visible = false; showNewMessagesButton.Visible = false;
} }
if (ToggleOpen || (InputBox != null && InputBox.Selected)) if (ToggleOpen)
{ {
openState += deltaTime * 5.0f; openState += deltaTime * 5.0f;
//delete all popup messages when the chatbox is open //delete all popup messages when the chatbox is open
@@ -133,7 +133,16 @@ namespace Barotrauma
case "size": case "size":
break; break;
default: default:
ChildStyles.Add(subElement.Name.ToString().ToLowerInvariant(), new GUIComponentStyle(subElement, style)); string styleName = subElement.Name.ToString().ToLowerInvariant();
if (ChildStyles.ContainsKey(styleName))
{
DebugConsole.ThrowError("UI style \"" + element.Name.ToString() + "\" contains multiple child styles with the same name (\"" + styleName + "\")!");
ChildStyles[styleName] = new GUIComponentStyle(subElement, style);
}
else
{
ChildStyles.Add(styleName, new GUIComponentStyle(subElement, style));
}
break; break;
} }
} }
@@ -78,19 +78,26 @@ namespace Barotrauma
public static readonly string[] rectComponentLabels = { "X", "Y", "W", "H" }; public static readonly string[] rectComponentLabels = { "X", "Y", "W", "H" };
public static readonly string[] colorComponentLabels = { "R", "G", "B", "A" }; public static readonly string[] colorComponentLabels = { "R", "G", "B", "A" };
public static float Scale public static Vector2 ReferenceResolution => new Vector2(1920f, 1080f);
{ public static float Scale => (GameMain.GraphicsWidth / ReferenceResolution.X + GameMain.GraphicsHeight / ReferenceResolution.Y) / 2.0f * GameSettings.HUDScale;
get { return (GameMain.GraphicsWidth / 1920.0f + GameMain.GraphicsHeight / 1080.0f) / 2.0f * GameSettings.HUDScale; } public static float xScale => GameMain.GraphicsWidth / ReferenceResolution.X * GameSettings.HUDScale;
} public static float yScale => GameMain.GraphicsHeight / ReferenceResolution.Y * GameSettings.HUDScale;
public static float HorizontalAspectRatio => GameMain.GraphicsWidth / (float)GameMain.GraphicsHeight;
public static float VerticalAspectRatio => GameMain.GraphicsHeight / (float)GameMain.GraphicsWidth;
public static float RelativeHorizontalAspectRatio => HorizontalAspectRatio / (ReferenceResolution.X / ReferenceResolution.Y);
public static float RelativeVerticalAspectRatio => VerticalAspectRatio / (ReferenceResolution.Y / ReferenceResolution.X);
public static float xScale public static float SlicedSpriteScale
{ {
get { return GameMain.GraphicsWidth / 1920.0f * GameSettings.HUDScale; } get
} {
if (Math.Abs(1.0f - Scale) < 0.1f)
public static float yScale {
{ //don't scale if very close to the "reference resolution"
get { return GameMain.GraphicsHeight / 1080.0f * GameSettings.HUDScale; } return 1.0f;
}
return Scale;
}
} }
public static GUIStyle Style; public static GUIStyle Style;
@@ -106,7 +113,7 @@ namespace Barotrauma
private static Sound[] sounds; private static Sound[] sounds;
private static bool pauseMenuOpen, settingsMenuOpen; private static bool pauseMenuOpen, settingsMenuOpen;
public static GUIFrame PauseMenu { get; private set; } public static GUIFrame PauseMenu { get; private set; }
private static Sprite arrow, lockIcon, checkmarkIcon, timerIcon; private static Sprite arrow;
public static bool HideCursor; public static bool HideCursor;
@@ -155,21 +162,6 @@ namespace Barotrauma
get { return arrow; } get { return arrow; }
} }
public static Sprite CheckmarkIcon
{
get { return checkmarkIcon; }
}
public static Sprite LockIcon
{
get { return lockIcon; }
}
public static Sprite TimerIcon
{
get { return timerIcon; }
}
public static Sprite InfoAreaBackground; public static Sprite InfoAreaBackground;
public static bool SettingsMenuOpen public static bool SettingsMenuOpen
@@ -263,13 +255,10 @@ namespace Barotrauma
t.SetData(new Color[] { Color.White });// fill the texture with white t.SetData(new Color[] { Color.White });// fill the texture with white
}); });
SubmarineIcon = new Sprite("Content/UI/IconAtlas.png", new Rectangle(452, 385, 182, 81), new Vector2(0.5f, 0.5f)); SubmarineIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(452, 385, 182, 81), new Vector2(0.5f, 0.5f));
arrow = new Sprite("Content/UI/IconAtlas.png", new Rectangle(392, 393, 49, 45), new Vector2(0.5f, 0.5f)); arrow = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(392, 393, 49, 45), new Vector2(0.5f, 0.5f));
SpeechBubbleIcon = new Sprite("Content/UI/IconAtlas.png", new Rectangle(385, 449, 66, 60), new Vector2(0.5f, 0.5f)); SpeechBubbleIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(385, 449, 66, 60), new Vector2(0.5f, 0.5f));
BrokenIcon = new Sprite("Content/UI/IconAtlas.png", new Rectangle(898, 386, 123, 123), new Vector2(0.5f, 0.5f)); BrokenIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(898, 386, 123, 123), new Vector2(0.5f, 0.5f));
lockIcon = new Sprite("Content/UI/UI_Atlas.png", new Rectangle(996, 677, 21, 25), new Vector2(0.5f, 0.5f));
checkmarkIcon = new Sprite("Content/UI/UI_Atlas.png", new Rectangle(932, 398, 33, 28), new Vector2(0.5f, 0.5f));
timerIcon = new Sprite("Content/UI/UI_Atlas.png", new Rectangle(997, 653, 18, 21), new Vector2(0.5f, 0.5f));
InfoAreaBackground = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(290, 320, 400, 300), new Vector2(0.0f, 0.0f)); InfoAreaBackground = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(290, 320, 400, 300), new Vector2(0.0f, 0.0f));
} }
@@ -300,17 +289,33 @@ namespace Barotrauma
string line1 = "Barotrauma Unstable v" + GameMain.Version; string line1 = "Barotrauma Unstable v" + GameMain.Version;
string line2 = "(" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")"; string line2 = "(" + AssemblyInfo.GetBuildString() + ", branch " + AssemblyInfo.GetGitBranch() + ", revision " + AssemblyInfo.GetGitRevision() + ")";
Rectangle watermarkRect = new Rectangle(-50, GameMain.GraphicsHeight - 80, 50 + (int)(Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X) * 1.2f), 100);
float alpha = 1.0f;
int yOffset = 0;
if (Screen.Selected == GameMain.GameScreen)
{
yOffset = -HUDLayoutSettings.ChatBoxArea.Height;
watermarkRect.Y += yOffset;
}
if (Screen.Selected == GameMain.GameScreen || Screen.Selected == GameMain.SubEditorScreen)
{
alpha = 0.2f;
}
Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw( Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0].Draw(
spriteBatch, new Rectangle(-50, GameMain.GraphicsHeight - 80, 50 + (int)(Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X) * 1.2f), 100), Color.Black * 0.8f); spriteBatch, watermarkRect, Color.Black * 0.8f * alpha);
LargeFont.DrawString(spriteBatch, line1, LargeFont.DrawString(spriteBatch, line1,
new Vector2(10, GameMain.GraphicsHeight - 30 - LargeFont.MeasureString(line1).Y), Color.White * 0.6f); new Vector2(10, GameMain.GraphicsHeight - 30 - LargeFont.MeasureString(line1).Y + yOffset), Color.White * 0.6f * alpha);
Font.DrawString(spriteBatch, line2, Font.DrawString(spriteBatch, line2,
new Vector2(10, GameMain.GraphicsHeight - 30), Color.White * 0.6f); new Vector2(10, GameMain.GraphicsHeight - 30 + yOffset), Color.White * 0.6f * alpha);
if (Screen.Selected != GameMain.GameScreen) if (Screen.Selected != GameMain.GameScreen)
{ {
var buttonRect = var buttonRect =
new Rectangle(20 + (int)Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X), GameMain.GraphicsHeight - (int)(45 * Scale), (int)(150 * Scale), (int)(40 * Scale)); new Rectangle(20 + (int)Math.Max(LargeFont.MeasureString(line1).X, Font.MeasureString(line2).X), GameMain.GraphicsHeight - (int)(45 * Scale) + yOffset, (int)(150 * Scale), (int)(40 * Scale));
if (DrawButton(spriteBatch, buttonRect, "Report Bug", Style.GetComponentStyle("GUIBugButton").Color * 0.8f)) if (DrawButton(spriteBatch, buttonRect, "Report Bug", Style.GetComponentStyle("GUIBugButton").Color * 0.8f))
{ {
GameMain.Instance.ShowBugReporter(); GameMain.Instance.ShowBugReporter();
@@ -521,7 +526,7 @@ namespace Barotrauma
spriteBatch.End(); spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable); spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
var sprite = MouseCursorSprites[(int) MouseCursor]; var sprite = MouseCursorSprites[(int) MouseCursor] ?? MouseCursorSprites[(int)CursorState.Default];
sprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, Color.White, sprite.Origin, 0f, Scale / 1.5f); sprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, Color.White, sprite.Origin, 0f, Scale / 1.5f);
spriteBatch.End(); spriteBatch.End();
@@ -1761,6 +1766,18 @@ namespace Barotrauma
//move the interfaces away from each other, in a random direction if they're at the same position //move the interfaces away from each other, in a random direction if they're at the same position
Vector2 moveAmount = centerDiff == Point.Zero ? Rand.Vector(1.0f) : Vector2.Normalize(centerDiff.ToVector2()); Vector2 moveAmount = centerDiff == Point.Zero ? Rand.Vector(1.0f) : Vector2.Normalize(centerDiff.ToVector2());
//if the horizontal move amount is much larger than vertical, only move horizontally
//(= attempt to place the elements side-by-side if they're more apart horizontally than vertically)
if (Math.Abs(moveAmount.X) > Math.Abs(moveAmount.Y) * 5.0f)
{
moveAmount.Y = 0.0f;
}
//same for the y-axis
else if (Math.Abs(moveAmount.Y) > Math.Abs(moveAmount.X) * 5.0f)
{
moveAmount.X = 0.0f;
}
//make sure we don't move the interfaces out of the screen //make sure we don't move the interfaces out of the screen
Vector2 moveAmount1 = ClampMoveAmount(rect1, area, moveAmount * 20.0f * rect1Area / (rect1Area + rect2Area)); Vector2 moveAmount1 = ClampMoveAmount(rect1, area, moveAmount * 20.0f * rect1Area / (rect1Area + rect2Area));
Vector2 moveAmount2 = ClampMoveAmount(rect2, area, -moveAmount * 20.0f * rect1Area / (rect1Area + rect2Area)); Vector2 moveAmount2 = ClampMoveAmount(rect2, area, -moveAmount * 20.0f * rect1Area / (rect1Area + rect2Area));
@@ -656,18 +656,18 @@ namespace Barotrauma
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle targetElement, List<ColorData> colorData = null) public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle targetElement, List<ColorData> colorData = null)
{ {
if (Tutorials.Tutorial.ContentRunning) return; if (Tutorials.Tutorial.ContentRunning) { return; }
int width = (int)(400 * GUI.Scale); int width = (int)(400 * GUI.Scale);
int height = (int)(18 * GUI.Scale); int height = (int)(18 * GUI.Scale);
Point padding = new Point((int)(20 * GUI.Scale), (int)(7 * GUI.Scale)); Point padding = new Point((int)(10 * GUI.Scale));
if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip) if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip)
{ {
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), colorData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip"); toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), colorData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
toolTipBlock.RectTransform.NonScaledSize = new Point( toolTipBlock.RectTransform.NonScaledSize = new Point(
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X), (int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y)); (int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
toolTipBlock.userData = toolTip; toolTipBlock.userData = toolTip;
} }
@@ -41,7 +41,17 @@ namespace Barotrauma
private bool dimensionsNeedsRecalculation; private bool dimensionsNeedsRecalculation;
// TODO: Define in styles? // TODO: Define in styles?
private int scrollBarSize = 25; private int ScrollBarSize
{
get
{
//use the average of the "desired" size and the scaled size
//scaling the bar linearly with the resolution tends to make them too large on large resolutions
float desiredSize = 25.0f;
float scaledSize = desiredSize * GUI.Scale;
return (int)((desiredSize + scaledSize) / 2.0f);
}
}
public bool SelectMultiple; public bool SelectMultiple;
@@ -162,7 +172,7 @@ namespace Barotrauma
/// Automatically hides the scroll bar when the content fits in. /// Automatically hides the scroll bar when the content fits in.
/// </summary> /// </summary>
public bool AutoHideScrollBar { get; set; } = true; public bool AutoHideScrollBar { get; set; } = true;
private bool IsScrollBarOnDefaultSide { get; set; }
public bool CanDragElements { get; set; } = false; public bool CanDragElements { get; set; } = false;
private GUIComponent draggedElement; private GUIComponent draggedElement;
@@ -171,7 +181,8 @@ namespace Barotrauma
public GUIComponent DraggedElement => draggedElement; public GUIComponent DraggedElement => draggedElement;
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "") : base(style, rectT) /// <param name="isScrollBarOnDefaultSide">For horizontal listbox, default side is on the bottom. For vertical, it's on the right.</param>
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "", bool isScrollBarOnDefaultSide = true) : base(style, rectT)
{ {
CanBeFocused = true; CanBeFocused = true;
selected = new List<GUIComponent>(); selected = new List<GUIComponent>();
@@ -196,20 +207,27 @@ namespace Barotrauma
{ {
this.color = color.Value; this.color = color.Value;
} }
IsScrollBarOnDefaultSide = isScrollBarOnDefaultSide;
Point size; Point size;
Anchor anchor; Anchor anchor;
if (isHorizontal) if (isHorizontal)
{ {
size = new Point((int)(Rect.Width - Padding.X - Padding.Z), (int)(scrollBarSize * GUI.Scale)); size = new Point((int)(Rect.Width - Padding.X - Padding.Z), (int)(ScrollBarSize * GUI.Scale));
anchor = Anchor.BottomCenter; anchor = isScrollBarOnDefaultSide ? Anchor.BottomCenter : Anchor.TopCenter;
} }
else else
{ {
size = new Point((int)(scrollBarSize * GUI.Scale), (int)(Rect.Height - Padding.Y - Padding.W)); // TODO: Should this be multiplied by the GUI.Scale as well?
anchor = Anchor.CenterRight; size = new Point(ScrollBarSize, (int)(Rect.Height - Padding.Y - Padding.W));
anchor = isScrollBarOnDefaultSide ? Anchor.CenterRight : Anchor.CenterLeft;
} }
ScrollBar = new GUIScrollBar(new RectTransform(size, rectT, anchor) ScrollBar = new GUIScrollBar(
{ AbsoluteOffset = isHorizontal ? new Point(0, (int)Padding.W) : new Point((int)Padding.Z, 0) }, new RectTransform(size, rectT, anchor)
{
AbsoluteOffset = isHorizontal ?
new Point(0, IsScrollBarOnDefaultSide ? (int)Padding.W : (int)Padding.Y) :
new Point(IsScrollBarOnDefaultSide ? (int)Padding.Z : (int)Padding.X, 0)
},
isHorizontal: isHorizontal); isHorizontal: isHorizontal);
UpdateScrollBarSize(); UpdateScrollBarSize();
Enabled = true; Enabled = true;
@@ -224,12 +242,15 @@ namespace Barotrauma
dimensionsNeedsRecalculation = false; dimensionsNeedsRecalculation = false;
ContentBackground.RectTransform.Resize(Rect.Size); ContentBackground.RectTransform.Resize(Rect.Size);
bool reduceScrollbarSize = KeepSpaceForScrollBar ? ScrollBarEnabled : ScrollBarVisible; bool reduceScrollbarSize = KeepSpaceForScrollBar ? ScrollBarEnabled : ScrollBarVisible;
Point contentSize = reduceScrollbarSize ? CalculateFrameSize(ScrollBar.IsHorizontal, scrollBarSize) : Rect.Size; Point contentSize = reduceScrollbarSize ? CalculateFrameSize(ScrollBar.IsHorizontal, ScrollBarSize) : Rect.Size;
Content.RectTransform.Resize(new Point((int)(contentSize.X - Padding.X - Padding.Z), (int)(contentSize.Y - Padding.Y - Padding.W))); Content.RectTransform.Resize(new Point((int)(contentSize.X - Padding.X - Padding.Z), (int)(contentSize.Y - Padding.Y - Padding.W)));
Content.RectTransform.AbsoluteOffset = new Point((int)Padding.X, (int)Padding.Y); if (!IsScrollBarOnDefaultSide) { Content.RectTransform.SetPosition(Anchor.BottomRight); }
Content.RectTransform.AbsoluteOffset = new Point(
IsScrollBarOnDefaultSide ? (int)Padding.X : (int)Padding.Z,
IsScrollBarOnDefaultSide ? (int)Padding.Y : (int)Padding.W);
ScrollBar.RectTransform.Resize(ScrollBar.IsHorizontal ? ScrollBar.RectTransform.Resize(ScrollBar.IsHorizontal ?
new Point((int)(Rect.Width - Padding.X - Padding.Z), (int)(scrollBarSize * GUI.Scale)) : new Point((int)(Rect.Width - Padding.X - Padding.Z), ScrollBarSize) :
new Point((int)(scrollBarSize * GUI.Scale), (int)(Rect.Height - Padding.Y - Padding.W))); new Point(ScrollBarSize, (int)(Rect.Height - Padding.Y - Padding.W)));
ScrollBar.RectTransform.AbsoluteOffset = ScrollBar.IsHorizontal ? ScrollBar.RectTransform.AbsoluteOffset = ScrollBar.IsHorizontal ?
new Point(0, (int)Padding.W) : new Point(0, (int)Padding.W) :
new Point((int)Padding.Z, 0); new Point((int)Padding.Z, 0);
@@ -1,4 +1,5 @@
using Microsoft.Xna.Framework; using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -62,8 +63,8 @@ namespace Barotrauma
public Color TextColorDark { get; private set; } = Color.Black * 0.9f; public Color TextColorDark { get; private set; } = Color.Black * 0.9f;
public Color TextColorDim { get; private set; } = Color.White * 0.6f; public Color TextColorDim { get; private set; } = Color.White * 0.6f;
public static Point ItemFrameMargin = new Point(50, 56); public static Point ItemFrameMargin = new Point(50, 56).Multiply(GUI.SlicedSpriteScale);
public static Point ItemFrameOffset = new Point(0, 3); public static Point ItemFrameOffset = new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
public GUIStyle(XElement element, GraphicsDevice graphicsDevice) public GUIStyle(XElement element, GraphicsDevice graphicsDevice)
{ {
@@ -76,10 +77,17 @@ namespace Barotrauma
switch (name) switch (name)
{ {
case "cursor": case "cursor":
foreach (var children in subElement.Descendants()) if (subElement.HasElements)
{ {
var index = children.GetAttributeInt("state", (int) CursorState.Default); foreach (var children in subElement.Descendants())
CursorSprite[index] = new Sprite(children); {
var index = children.GetAttributeInt("state", (int)CursorState.Default);
CursorSprite[index] = new Sprite(children);
}
}
else
{
CursorSprite[(int)CursorState.Default] = new Sprite(subElement);
} }
break; break;
case "green": case "green":
@@ -85,7 +85,7 @@ namespace Barotrauma
if (Text == newText) { return; } if (Text == newText) { return; }
//reset scale, it gets recalculated in SetTextPos //reset scale, it gets recalculated in SetTextPos
if (autoScale) { textScale = 1.0f; } if (autoScaleHorizontal || autoScaleVertical) { textScale = 1.0f; }
text = newText; text = newText;
wrappedText = newText; wrappedText = newText;
@@ -132,19 +132,36 @@ namespace Barotrauma
} }
} }
private bool autoScale; private bool autoScaleHorizontal, autoScaleVertical;
/// <summary> /// <summary>
/// When enabled, the text is automatically scaled down to fit the textblock. /// When enabled, the text is automatically scaled down to fit the textblock horizontally.
/// </summary> /// </summary>
public bool AutoScale public bool AutoScaleHorizontal
{ {
get { return autoScale; } get { return autoScaleHorizontal; }
set set
{ {
if (autoScale == value) return; if (autoScaleHorizontal == value) { return; }
autoScale = value; autoScaleHorizontal = value;
if (autoScale) if (autoScaleHorizontal)
{
SetTextPos();
}
}
}
/// <summary>
/// When enabled, the text is automatically scaled down to fit the textblock vertically.
/// </summary>
public bool AutoScaleVertical
{
get { return autoScaleVertical; }
set
{
if (autoScaleVertical == value) { return; }
autoScaleVertical = value;
if (autoScaleVertical)
{ {
SetTextPos(); SetTextPos();
} }
@@ -309,7 +326,7 @@ namespace Barotrauma
public void SetTextPos() public void SetTextPos()
{ {
if (text == null) return; if (text == null) { return; }
censoredText = ""; censoredText = "";
for (int i = 0; i < text.Length; i++) for (int i = 0; i < text.Length; i++)
@@ -337,12 +354,13 @@ namespace Barotrauma
Vector2 minSize = new Vector2( Vector2 minSize = new Vector2(
Math.Max(rect.Width - padding.X - padding.Z, 5.0f), Math.Max(rect.Width - padding.X - padding.Z, 5.0f),
Math.Max(rect.Height - padding.Y - padding.W, 5.0f)); Math.Max(rect.Height - padding.Y - padding.W, 5.0f));
if (autoScale && textScale > 0.1f && if (!autoScaleHorizontal) { minSize.X = float.MaxValue; }
if (!Wrap && !autoScaleVertical) { minSize.Y = float.MaxValue; }
if ((autoScaleHorizontal || autoScaleVertical) && textScale > 0.1f &&
(TextSize.X * textScale > minSize.X || TextSize.Y * textScale > minSize.Y)) (TextSize.X * textScale > minSize.X || TextSize.Y * textScale > minSize.Y))
{ {
TextScale = Math.Max(0.1f, Math.Min( TextScale = Math.Max(0.1f, Math.Min(minSize.X / TextSize.X, minSize.Y / TextSize.Y)) - 0.01f;
(rect.Width - padding.X - padding.Z) / TextSize.X,
(rect.Height - padding.Y - padding.W) / TextSize.Y)) - 0.01f;
return; return;
} }
@@ -490,20 +508,30 @@ namespace Barotrauma
/// <summary> /// <summary>
/// Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text within the block. /// Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text within the block.
/// </summary> /// </summary>
public static void AutoScaleAndNormalize(IEnumerable<GUITextBlock> textBlocks, float? defaultScale = null) public static void AutoScaleAndNormalize(bool scaleHorizontal = true, bool scaleVertical = false, params GUITextBlock[] textBlocks)
{
AutoScaleAndNormalize(textBlocks.AsEnumerable<GUITextBlock>(), scaleHorizontal, scaleVertical);
}
/// <summary>
/// Set the text scale of the GUITextBlocks so that they all use the same scale and can fit the text within the block.
/// </summary>
public static void AutoScaleAndNormalize(IEnumerable<GUITextBlock> textBlocks, bool scaleHorizontal = true, bool scaleVertical = false, float? defaultScale = null)
{ {
if (!textBlocks.Any()) { return; } if (!textBlocks.Any()) { return; }
float minScale = Math.Max(textBlocks.First().TextScale, 1.0f); float minScale = Math.Max(textBlocks.First().TextScale, 1.0f);
foreach (GUITextBlock textBlock in textBlocks) foreach (GUITextBlock textBlock in textBlocks)
{ {
if (defaultScale.HasValue) { textBlock.TextScale = defaultScale.Value; } if (defaultScale.HasValue) { textBlock.TextScale = defaultScale.Value; }
textBlock.AutoScale = true; textBlock.AutoScaleHorizontal = scaleHorizontal;
textBlock.AutoScaleVertical = scaleVertical;
minScale = Math.Min(textBlock.TextScale, minScale); minScale = Math.Min(textBlock.TextScale, minScale);
} }
foreach (GUITextBlock textBlock in textBlocks) foreach (GUITextBlock textBlock in textBlocks)
{ {
textBlock.AutoScale = false; textBlock.AutoScaleHorizontal = false;
textBlock.AutoScaleVertical = false;
textBlock.TextScale = minScale; textBlock.TextScale = minScale;
} }
} }
@@ -75,9 +75,8 @@ namespace Barotrauma
set { textBlock.TextGetter = value; } set { textBlock.TextGetter = value; }
} }
// TODO: fix implicit hiding private new bool selected;
private bool selected; public new bool Selected
public bool Selected
{ {
get get
{ {
@@ -457,13 +456,13 @@ namespace Barotrauma
return currPosition != null ? currPosition.Item2 : textBlock.Text.Length; return currPosition != null ? currPosition.Item2 : textBlock.Text.Length;
} }
public void Select() public void Select(int forcedCaretIndex = -1)
{ {
if (memento.Current == null) if (memento.Current == null)
{ {
memento.Store(Text); memento.Store(Text);
} }
CaretIndex = GetCaretIndexFromScreenPos(PlayerInput.MousePosition); CaretIndex = forcedCaretIndex == - 1 ? GetCaretIndexFromScreenPos(PlayerInput.MousePosition) : forcedCaretIndex;
ClearSelection(); ClearSelection();
selected = true; selected = true;
GUI.KeyboardDispatcher.Subscriber = this; GUI.KeyboardDispatcher.Subscriber = this;
@@ -30,10 +30,6 @@ namespace Barotrauma
get; private set; get; private set;
} }
public static Rectangle InventoryAreaUpper
{
get; private set;
}
public static Rectangle CrewArea public static Rectangle CrewArea
{ {
@@ -110,7 +106,7 @@ namespace Barotrauma
{ {
Padding = (int)(10 * GUI.Scale); Padding = (int)(10 * GUI.Scale);
if (inventoryTopY == 0) inventoryTopY = GameMain.GraphicsHeight; if (inventoryTopY == 0) { inventoryTopY = GameMain.GraphicsHeight - 30; }
//slice from the top of the screen for misc buttons (info, end round, server controls) //slice from the top of the screen for misc buttons (info, end round, server controls)
ButtonAreaTop = new Rectangle(Padding, Padding, GameMain.GraphicsWidth - Padding * 2, (int)(50 * GUI.Scale)); ButtonAreaTop = new Rectangle(Padding, Padding, GameMain.GraphicsWidth - Padding * 2, (int)(50 * GUI.Scale));
@@ -124,7 +120,7 @@ namespace Barotrauma
int healthBarHeight = (int)Math.Max(15f * GUI.Scale, 12.5f); int healthBarHeight = (int)Math.Max(15f * GUI.Scale, 12.5f);
int afflictionAreaHeight = (int)(50 * GUI.Scale); int afflictionAreaHeight = (int)(50 * GUI.Scale);
HealthBarAreaLeft = new Rectangle(PortraitArea.X, PortraitArea.Y + Padding / 2 + portraitSize, healthBarWidth, healthBarHeight); HealthBarAreaLeft = new Rectangle(PortraitArea.X, PortraitArea.Y + Padding / 2 + portraitSize, healthBarWidth, healthBarHeight);
AfflictionAreaLeft = new Rectangle(Padding, HealthBarAreaLeft.Y - afflictionAreaHeight - Padding, healthBarWidth, afflictionAreaHeight); AfflictionAreaLeft = new Rectangle(PortraitArea.X, HealthBarAreaLeft.Y + healthBarHeight + Padding, healthBarWidth, afflictionAreaHeight);
//HealthBarAreaRight = new Rectangle(Padding, GameMain.GraphicsHeight - healthBarHeight - Padding, healthBarWidth, healthBarHeight); //HealthBarAreaRight = new Rectangle(Padding, GameMain.GraphicsHeight - healthBarHeight - Padding, healthBarWidth, healthBarHeight);
/*if (HealthBarAreaRight.Y + healthBarHeight * 0.75f < PortraitArea.Y) /*if (HealthBarAreaRight.Y + healthBarHeight * 0.75f < PortraitArea.Y)
@@ -136,14 +132,6 @@ namespace Barotrauma
int messageAreaWidth = GameMain.GraphicsWidth / 3; int messageAreaWidth = GameMain.GraphicsWidth / 3;
MessageAreaTop = new Rectangle((GameMain.GraphicsWidth - messageAreaWidth) / 2, ButtonAreaTop.Bottom, messageAreaWidth, ButtonAreaTop.Height); MessageAreaTop = new Rectangle((GameMain.GraphicsWidth - messageAreaWidth) / 2, ButtonAreaTop.Bottom, messageAreaWidth, ButtonAreaTop.Height);
CrewArea = new Rectangle(HealthBarAreaLeft.Right + Padding, MessageAreaTop.Bottom + Padding,
GameMain.GraphicsWidth - HealthBarAreaLeft.Right - 2 * Padding, (int)(0.6f * portraitSize));
//slice for the upper slots of the inventory (clothes, id card, headset)
int inventoryAreaUpperWidth = (int)(GameMain.GraphicsWidth * 0.2f);
int inventoryAreaUpperHeight = (int)(GameMain.GraphicsHeight * 0.2f);
InventoryAreaUpper = new Rectangle(GameMain.GraphicsWidth - inventoryAreaUpperWidth - Padding, CrewArea.Y, inventoryAreaUpperWidth, inventoryAreaUpperHeight);
int toggleButtonWidth = (int)(ChatBox.ToggleButtonWidthRaw * GUI.Scale); int toggleButtonWidth = (int)(ChatBox.ToggleButtonWidthRaw * GUI.Scale);
int chatBoxWidth = (int)(475 * GUI.Scale); int chatBoxWidth = (int)(475 * GUI.Scale);
int chatBoxHeight = (int)Math.Max(GameMain.GraphicsHeight * 0.22f, 150); int chatBoxHeight = (int)Math.Max(GameMain.GraphicsHeight * 0.22f, 150);
@@ -153,8 +141,11 @@ namespace Barotrauma
int objectiveAnchorOffsetY = (int)(150 * GUI.Scale); int objectiveAnchorOffsetY = (int)(150 * GUI.Scale);
ObjectiveAnchor = new Rectangle(Padding, ChatBoxArea.Y - objectiveAnchorOffsetY, objectiveAnchorWidth, 0); ObjectiveAnchor = new Rectangle(Padding, ChatBoxArea.Y - objectiveAnchorOffsetY, objectiveAnchorWidth, 0);
int lowerAreaHeight = (int)Math.Min(GameMain.GraphicsHeight * 0.25f, 280); var crewAreaY = AfflictionAreaLeft.Bottom + Padding;
InventoryAreaLower = new Rectangle(Padding, GameMain.GraphicsHeight - lowerAreaHeight, GameMain.GraphicsWidth - Padding * 2, lowerAreaHeight); var crewAreaHeight = ObjectiveAnchor.Top - Padding - crewAreaY;
CrewArea = new Rectangle(Padding, crewAreaY, (int)Math.Max(400 * GUI.Scale, 400), crewAreaHeight);
InventoryAreaLower = new Rectangle(Padding, inventoryTopY, GameMain.GraphicsWidth - Padding * 2, GameMain.GraphicsHeight - inventoryTopY);
int healthWindowWidth = (int)(GameMain.GraphicsWidth * 0.5f); int healthWindowWidth = (int)(GameMain.GraphicsWidth * 0.5f);
int healthWindowHeight = (int)(GameMain.GraphicsWidth * 0.5f * 0.65f); int healthWindowHeight = (int)(GameMain.GraphicsWidth * 0.5f * 0.65f);
@@ -168,7 +159,6 @@ namespace Barotrauma
{ {
GUI.DrawRectangle(spriteBatch, ButtonAreaTop, Color.White * 0.5f); GUI.DrawRectangle(spriteBatch, ButtonAreaTop, Color.White * 0.5f);
GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUI.Style.Orange * 0.5f); GUI.DrawRectangle(spriteBatch, MessageAreaTop, GUI.Style.Orange * 0.5f);
GUI.DrawRectangle(spriteBatch, InventoryAreaUpper, Color.Yellow * 0.5f);
GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f); GUI.DrawRectangle(spriteBatch, CrewArea, Color.Blue * 0.5f);
GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f); GUI.DrawRectangle(spriteBatch, ChatBoxArea, Color.Cyan * 0.5f);
GUI.DrawRectangle(spriteBatch, HealthBarAreaLeft, Color.Red * 0.5f); GUI.DrawRectangle(spriteBatch, HealthBarAreaLeft, Color.Red * 0.5f);
@@ -293,10 +293,15 @@ namespace Barotrauma
} }
} }
private ScaleBasis _scaleBasis;
public ScaleBasis ScaleBasis public ScaleBasis ScaleBasis
{ {
get; get { return _scaleBasis; }
private set; set
{
_scaleBasis = value;
RecalculateAbsoluteSize();
}
} }
public bool IsLastChild public bool IsLastChild
@@ -336,7 +341,7 @@ namespace Barotrauma
public RectTransform(Vector2 relativeSize, RectTransform parent, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, Point? minSize = null, Point? maxSize = null, ScaleBasis scaleBasis = ScaleBasis.Normal) public RectTransform(Vector2 relativeSize, RectTransform parent, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, Point? minSize = null, Point? maxSize = null, ScaleBasis scaleBasis = ScaleBasis.Normal)
{ {
Init(parent, anchor, pivot); Init(parent, anchor, pivot);
this.ScaleBasis = scaleBasis; _scaleBasis = scaleBasis;
this.relativeSize = relativeSize; this.relativeSize = relativeSize;
this.minSize = minSize; this.minSize = minSize;
this.maxSize = maxSize; this.maxSize = maxSize;
@@ -348,19 +353,23 @@ namespace Barotrauma
} }
/// <summary> /// <summary>
/// By default, elements defined with an absolute size (in pixels), will be treated as fixed sized. /// By default, elements defined with an absolute size (in pixels) will scale with the parent.
/// This can be changed by setting IsFixedSize to false. /// This can be changed by setting IsFixedSize to true.
/// </summary> /// </summary>
public RectTransform(Point absoluteSize, RectTransform parent = null, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null) public RectTransform(Point absoluteSize, RectTransform parent = null, Anchor anchor = Anchor.TopLeft, Pivot? pivot = null, ScaleBasis scaleBasis = ScaleBasis.Normal, bool isFixedSize = false)
{ {
Init(parent, anchor, pivot); Init(parent, anchor, pivot);
this.ScaleBasis = ScaleBasis.Normal; _scaleBasis = scaleBasis;
this.nonScaledSize = absoluteSize; this.nonScaledSize = absoluteSize;
RecalculateScale(); RecalculateScale();
RecalculateRelativeSize(); RecalculateRelativeSize();
if (scaleBasis != ScaleBasis.Normal)
{
RecalculateAbsoluteSize();
}
RecalculateAnchorPoint(); RecalculateAnchorPoint();
RecalculatePivotOffset(); RecalculatePivotOffset();
IsFixedSize = true; IsFixedSize = isFixedSize;
parent?.ChildrenChanged?.Invoke(this); parent?.ChildrenChanged?.Invoke(this);
} }
@@ -370,6 +379,7 @@ namespace Barotrauma
Enum.TryParse(element.GetAttributeString("pivot", anchor.ToString()), out Pivot pivot); Enum.TryParse(element.GetAttributeString("pivot", anchor.ToString()), out Pivot pivot);
Point? minSize = null, maxSize = null; Point? minSize = null, maxSize = null;
ScaleBasis scaleBasis = ScaleBasis.Normal;
if (element.Attribute("minsize") != null) if (element.Attribute("minsize") != null)
{ {
minSize = element.GetAttributePoint("minsize", Point.Zero); minSize = element.GetAttributePoint("minsize", Point.Zero);
@@ -378,11 +388,15 @@ namespace Barotrauma
{ {
maxSize = element.GetAttributePoint("maxsize", new Point(1000, 1000)); maxSize = element.GetAttributePoint("maxsize", new Point(1000, 1000));
} }
string sb = element.GetAttributeString("scalebasis", null);
if (sb != null)
{
Enum.TryParse(sb, ignoreCase: true, out scaleBasis);
}
RectTransform rectTransform; RectTransform rectTransform;
if (element.Attribute("absolutesize") != null) if (element.Attribute("absolutesize") != null)
{ {
rectTransform = new RectTransform(element.GetAttributePoint("absolutesize", new Point(1000, 1000)), parent, anchor, pivot) rectTransform = new RectTransform(element.GetAttributePoint("absolutesize", new Point(1000, 1000)), parent, anchor, pivot, scaleBasis)
{ {
minSize = minSize, minSize = minSize,
maxSize = maxSize maxSize = maxSize
@@ -390,7 +404,7 @@ namespace Barotrauma
} }
else else
{ {
rectTransform = new RectTransform(element.GetAttributeVector2("relativesize", Vector2.One), parent, anchor, pivot, minSize, maxSize); rectTransform = new RectTransform(element.GetAttributeVector2("relativesize", Vector2.One), parent, anchor, pivot, minSize, maxSize, scaleBasis);
} }
rectTransform.RelativeOffset = element.GetAttributeVector2("relativeoffset", Vector2.Zero); rectTransform.RelativeOffset = element.GetAttributeVector2("relativeoffset", Vector2.Zero);
rectTransform.AbsoluteOffset = element.GetAttributePoint("absoluteoffset", Point.Zero); rectTransform.AbsoluteOffset = element.GetAttributePoint("absoluteoffset", Point.Zero);
@@ -438,37 +452,37 @@ namespace Barotrauma
protected void RecalculateAbsoluteSize() protected void RecalculateAbsoluteSize()
{ {
Point size = NonScaledParentRect.Size; Point size = NonScaledParentRect.Size;
if (ScaleBasis == ScaleBasis.BothWidth) switch (ScaleBasis)
{ {
size.Y = size.X; case ScaleBasis.BothWidth:
}
else if (ScaleBasis == ScaleBasis.BothHeight)
{
size.X = size.Y;
}
else if (ScaleBasis == ScaleBasis.Smallest)
{
if (size.X < size.Y)
{
size.Y = size.X; size.Y = size.X;
} break;
else case ScaleBasis.BothHeight:
{
size.X = size.Y; size.X = size.Y;
} break;
case ScaleBasis.Smallest:
if (size.X < size.Y)
{
size.Y = size.X;
}
else
{
size.X = size.Y;
}
break;
case ScaleBasis.Largest:
if (size.X > size.Y)
{
size.Y = size.X;
}
else
{
size.X = size.Y;
}
break;
} }
else if (ScaleBasis == ScaleBasis.Largest) size = size.Multiply(RelativeSize);
{ nonScaledSize = size.Clamp(MinSize, MaxSize);
if (size.X > size.Y)
{
size.Y = size.X;
}
else
{
size.X = size.Y;
}
}
nonScaledSize = size.Multiply(RelativeSize).Clamp(MinSize, MaxSize);
recalculateRect = true; recalculateRect = true;
SizeChanged?.Invoke(); SizeChanged?.Invoke();
} }
@@ -684,6 +698,44 @@ namespace Barotrauma
children[i].GUIComponent.AddToGUIUpdateList(ignoreChildren, order); children[i].GUIComponent.AddToGUIUpdateList(ignoreChildren, order);
} }
} }
public void MatchPivotToAnchor() => MatchPivotToAnchor(Anchor);
public void MoveOverTime(Point targetPos, float duration)
{
CoroutineManager.StartCoroutine(DoMoveAnimation(targetPos, duration));
}
public void ScaleOverTime(Point targetSize, float duration)
{
CoroutineManager.StartCoroutine(DoScaleAnimation(targetSize, duration));
}
private IEnumerable<object> DoMoveAnimation(Point targetPos, float duration)
{
Vector2 startPos = AbsoluteOffset.ToVector2();
float t = 0.0f;
while (t < duration && duration > 0.0f)
{
t += CoroutineManager.DeltaTime;
AbsoluteOffset = Vector2.SmoothStep(startPos, targetPos.ToVector2(), t / duration).ToPoint();
yield return CoroutineStatus.Running;
}
AbsoluteOffset = targetPos;
yield return CoroutineStatus.Success;
}
private IEnumerable<object> DoScaleAnimation(Point targetSize, float duration)
{
Vector2 startSize = NonScaledSize.ToVector2();
float t = 0.0f;
while (t < duration && duration > 0.0f)
{
t += CoroutineManager.DeltaTime;
NonScaledSize = Vector2.SmoothStep(startSize, targetSize.ToVector2(), t / duration).ToPoint();
yield return CoroutineStatus.Running;
}
NonScaledSize = targetSize;
yield return CoroutineStatus.Success;
}
#endregion #endregion
#region Static methods #region Static methods
@@ -101,10 +101,9 @@ namespace Barotrauma
Vector2 scale = Vector2.One; Vector2 scale = Vector2.One;
scale.Y = MathHelper.Clamp((float)rect.Height / (Slices[0].Height + Slices[6].Height), 0, 1); scale.Y = MathHelper.Clamp((float)rect.Height / (Slices[0].Height + Slices[6].Height), 0, 1);
scale.X = MathHelper.Clamp((float)rect.Width / (Slices[0].Width + Slices[2].Width), 0, 1); scale.X = MathHelper.Clamp((float)rect.Width / (Slices[0].Width + Slices[2].Width), 0, 1);
scale.X = scale.Y = Math.Min(scale.X, scale.Y); scale.X = scale.Y = Math.Min(Math.Min(scale.X, scale.Y), GUI.SlicedSpriteScale);
int centerHeight = rect.Height - (int)((Slices[0].Height + Slices[6].Height) * scale.Y); int centerHeight = rect.Height - (int)((Slices[0].Height + Slices[6].Height) * scale.Y);
int centerWidth = rect.Width - (int)((Slices[0].Width + Slices[2].Width) * scale.X); int centerWidth = rect.Width - (int)((Slices[0].Width + Slices[2].Width) * scale.X);
@@ -20,7 +20,7 @@ namespace Barotrauma
private GUICustomComponent videoView; private GUICustomComponent videoView;
private GUIButton okButton; private GUIButton okButton;
private Color backgroundColor = new Color(0f, 0f, 0f, 1f); private Color backgroundColor = new Color(0f, 0f, 0f, 0.8f);
private Action callbackOnStop; private Action callbackOnStop;
private Point scaledVideoResolution; private Point scaledVideoResolution;
@@ -62,8 +62,8 @@ namespace Barotrauma
int width = scaledVideoResolution.X; int width = scaledVideoResolution.X;
int height = scaledVideoResolution.Y; int height = scaledVideoResolution.Y;
background = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor); background = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas, Anchor.Center), style: null, color: backgroundColor);
videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center), "SonarFrame"); videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center), style: "InnerFrame");
if (useTextOnRightSide) if (useTextOnRightSide)
{ {
@@ -480,6 +480,7 @@ namespace Barotrauma
LevelGenerationParams.LoadPresets(); LevelGenerationParams.LoadPresets();
ScriptedEventSet.LoadPrefabs(); ScriptedEventSet.LoadPrefabs();
AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings));
TitleScreen.LoadState = 50.0f; TitleScreen.LoadState = 50.0f;
yield return CoroutineStatus.Running; yield return CoroutineStatus.Running;
File diff suppressed because it is too large Load Diff
@@ -98,7 +98,7 @@ namespace Barotrauma.Tutorials
var repairOrder = Order.GetPrefab("repairsystems"); var repairOrder = Order.GetPrefab("repairsystems");
mechanic_repairIcon = repairOrder.SymbolSprite; mechanic_repairIcon = repairOrder.SymbolSprite;
mechanic_repairIconColor = repairOrder.Color; mechanic_repairIconColor = repairOrder.Color;
mechanic_weldIcon = new Sprite("Content/UI/IconAtlas.png", new Rectangle(1, 256, 127, 127), new Vector2(0.5f, 0.5f)); mechanic_weldIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(1, 256, 127, 127), new Vector2(0.5f, 0.5f));
// Other tutorial items // Other tutorial items
tutorial_securityFinalDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_securityfinaldoorlight")).GetComponent<LightComponent>(); tutorial_securityFinalDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_securityfinaldoorlight")).GetComponent<LightComponent>();
@@ -95,14 +95,14 @@ namespace Barotrauma
limbSlotIcons = new Dictionary<InvSlotType, Sprite>(); limbSlotIcons = new Dictionary<InvSlotType, Sprite>();
int margin = 2; int margin = 2;
limbSlotIcons.Add(InvSlotType.Headset, new Sprite("Content/UI/IconAtlas.png", new Rectangle(384 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.Headset, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(384 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.InnerClothes, new Sprite("Content/UI/IconAtlas.png", new Rectangle(512 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.InnerClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(512 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.Card, new Sprite("Content/UI/IconAtlas.png", new Rectangle(640 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.Card, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(640 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.Head, new Sprite("Content/UI/IconAtlas.png", new Rectangle(896 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.Head, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(896 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(640 + margin, 0 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(634, 0, 128, 128)));
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(768 + margin, 0 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(762, 0, 128, 128)));
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/IconAtlas.png", new Rectangle(768 + margin, 896 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(256 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
} }
SlotPositions = new Vector2[SlotTypes.Length]; SlotPositions = new Vector2[SlotTypes.Length];
CurrentLayout = Layout.Default; CurrentLayout = Layout.Default;
@@ -165,7 +165,7 @@ namespace Barotrauma
slots[i] = new InventorySlot(slotRect) slots[i] = new InventorySlot(slotRect)
{ {
SubInventoryDir = Math.Sign(HUDLayoutSettings.InventoryAreaUpper.Bottom - slotRect.Center.Y), SubInventoryDir = Math.Sign(GameMain.GraphicsHeight / 2 - slotRect.Center.Y),
Disabled = false, Disabled = false,
SlotSprite = slotSprite, SlotSprite = slotSprite,
Color = SlotTypes[i] == InvSlotType.Any ? Color.White * 0.2f : Color.White * 0.4f Color = SlotTypes[i] == InvSlotType.Any ? Color.White * 0.2f : Color.White * 0.4f
@@ -532,7 +532,7 @@ namespace Barotrauma
} }
} }
if (character.SelectedCharacter == null) // Permanently open subinventories only available when the default UI layout is in use -> not when grabbing characters if (character == Character.Controlled && character.SelectedCharacter == null) // Permanently open subinventories only available when the default UI layout is in use -> not when grabbing characters
{ {
//remove the highlighted slots of other characters' inventories when not grabbing anyone //remove the highlighted slots of other characters' inventories when not grabbing anyone
highlightedSubInventorySlots.RemoveWhere(s => s.ParentInventory != this && s.ParentInventory?.Owner is Character); highlightedSubInventorySlots.RemoveWhere(s => s.ParentInventory != this && s.ParentInventory?.Owner is Character);
@@ -622,32 +622,11 @@ namespace Barotrauma
} }
var quickUseAction = GetQuickUseAction(item, allowEquip: true, allowInventorySwap: false, allowApplyTreatment: false); var quickUseAction = GetQuickUseAction(item, allowEquip: true, allowInventorySwap: false, allowApplyTreatment: false);
slot.QuickUseButtonToolTip = quickUseAction == QuickUseAction.None ?
if (quickUseAction != QuickUseAction.Drop)
{
slot.QuickUseButtonToolTip = quickUseAction == QuickUseAction.None ?
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", character.SelectedItems.FirstOrDefault(i => i != null)?.Name); "" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", character.SelectedItems.FirstOrDefault(i => i != null)?.Name);
//equipped item that can't be put in the inventory, use delayed dropping
if (quickUseAction == QuickUseAction.Drop)
{
slot.QuickUseButtonToolTip =
TextManager.Get("QuickUseAction.HoldToUnequip", returnNull: true) ??
(GameMain.Config.Language == "English" ? "Hold to unequip" : TextManager.Get("QuickUseAction.Unequip"));
if (PlayerInput.LeftButtonHeld())
{
slot.QuickUseTimer = Math.Max(0.1f, slot.QuickUseTimer + deltaTime);
if (slot.QuickUseTimer >= 1.0f)
{
item.Drop(Character.Controlled);
GUI.PlayUISound(GUISoundType.DropItem);
}
}
else
{
slot.QuickUseTimer = Math.Max(0.0f, slot.QuickUseTimer - deltaTime * 5.0f);
}
}
else
{
if (PlayerInput.PrimaryMouseButtonDown()) slot.EquipButtonState = GUIComponent.ComponentState.Pressed; if (PlayerInput.PrimaryMouseButtonDown()) slot.EquipButtonState = GUIComponent.ComponentState.Pressed;
if (PlayerInput.PrimaryMouseButtonClicked()) if (PlayerInput.PrimaryMouseButtonClicked())
{ {
@@ -994,13 +973,13 @@ namespace Barotrauma
} }
if (Locked) { color *= 0.3f; } if (Locked) { color *= 0.3f; }
var quickUseIndicator = Items[i].AllowedSlots.Any(a => a == InvSlotType.Any) ? if (!Items[i].AllowedSlots.Any(a => a == InvSlotType.Any))
EquipIndicator : DropIndicator; {
var quickUseHighlight = Items[i].AllowedSlots.Any(a => a == InvSlotType.Any) ? continue;
EquipIndicatorHighlight : DropIndicatorHighlight; }
quickUseIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, quickUseIndicator.Origin, 0, UIScale); EquipIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquipIndicator.Origin, 0, UIScale);
slots[i].QuickUseTimer = Math.Min(slots[i].QuickUseTimer, 1.0f); /*slots[i].QuickUseTimer = Math.Min(slots[i].QuickUseTimer, 1.0f);
if (slots[i].QuickUseTimer > 0.0f) if (slots[i].QuickUseTimer > 0.0f)
{ {
float indicatorFillAmount = character.HasEquippedItem(Items[i]) ? 1.0f - slots[i].QuickUseTimer : slots[i].QuickUseTimer; float indicatorFillAmount = character.HasEquippedItem(Items[i]) ? 1.0f - slots[i].QuickUseTimer : slots[i].QuickUseTimer;
@@ -1012,9 +991,9 @@ namespace Barotrauma
null, null,
Vector2.One * UIScale * 0.85f); Vector2.One * UIScale * 0.85f);
} }
else if (character.HasEquippedItem(Items[i])) else*/ if (character.HasEquippedItem(Items[i]))
{ {
quickUseHighlight.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color * 0.9f, quickUseHighlight.Origin, 0, UIScale * 0.85f); EquipIndicatorHighlight.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color * 0.9f, EquipIndicatorHighlight.Origin, 0, UIScale * 0.85f);
} }
} }
@@ -117,33 +117,38 @@ namespace Barotrauma.Items.Components
else else
{ {
//if a GUIFrame has been defined, draw the inventory inside it //if a GUIFrame has been defined, draw the inventory inside it
CreateGUI();
var content = new GUIFrame(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset }, GameMain.Instance.OnResolutionChanged += () => { GuiFrame.ClearChildren(); CreateGUI(); };
style: null)
{
CanBeFocused = false
};
string labelText = GetUILabel();
GUITextBlock label = null;
if (!string.IsNullOrEmpty(labelText))
{
label = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform, Anchor.TopCenter),
labelText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
}
float minInventoryAreaSize = 0.5f;
guiCustomComponent = new GUICustomComponent(
new RectTransform(new Vector2(1.0f, label == null ? 1.0f : Math.Max(1.0f - label.RectTransform.RelativeSize.Y, minInventoryAreaSize)), content.RectTransform, Anchor.BottomCenter),
onDraw: (SpriteBatch spriteBatch, GUICustomComponent component) => { Inventory.Draw(spriteBatch); },
onUpdate: null)
{
CanBeFocused = false
};
Inventory.RectTransform = guiCustomComponent.RectTransform;
} }
} }
private void CreateGUI()
{
var content = new GUIFrame(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset },
style: null)
{
CanBeFocused = false
};
string labelText = GetUILabel();
GUITextBlock label = null;
if (!string.IsNullOrEmpty(labelText))
{
label = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform, Anchor.TopCenter),
labelText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
}
float minInventoryAreaSize = 0.5f;
guiCustomComponent = new GUICustomComponent(
new RectTransform(new Vector2(1.0f, label == null ? 1.0f : Math.Max(1.0f - label.RectTransform.RelativeSize.Y, minInventoryAreaSize)), content.RectTransform, Anchor.BottomCenter),
onDraw: (SpriteBatch spriteBatch, GUICustomComponent component) => { Inventory.Draw(spriteBatch); },
onUpdate: null)
{
CanBeFocused = false
};
Inventory.RectTransform = guiCustomComponent.RectTransform;
}
public string GetUILabel() public string GetUILabel()
{ {
if (UILabel == string.Empty) { return string.Empty; } if (UILabel == string.Empty) { return string.Empty; }
@@ -22,68 +22,99 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific(XElement element) partial void InitProjSpecific(XElement element)
{ {
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter) CreateGUI();
GameMain.Instance.OnResolutionChanged += () =>
{
GuiFrame.ClearChildren();
CreateGUI();
OnItemLoadedProjSpecific();
};
}
private void CreateGUI()
{
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.90f, 0.80f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
{ {
Stretch = true, Stretch = true,
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
var topFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null); var topFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null);
var paddedLine = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), topFrame.RectTransform, Anchor.TopCenter), childAnchor: Anchor.CenterLeft, isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.02f
};
var inputText = new GUITextBlock(new RectTransform(new Vector2(0f, 1.0f), paddedLine.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
new GUIFrame(new RectTransform(new Vector2(1f, 1.0f), paddedLine.RectTransform), style: "HorizontalLine");
// Resize GUITextBlock width according to the text length // === INPUT LABEL === //
inputText.RectTransform.Resize(new Point((int)inputText.Font.MeasureString(inputText.Text).X, inputText.RectTransform.Rect.Height)); var inputLabelArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.15f), topFrame.RectTransform, Anchor.TopCenter), childAnchor: Anchor.CenterLeft, isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.05f
};
var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, inputLabelArea.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
new GUIFrame(new RectTransform(Vector2.One, inputLabelArea.RectTransform), style: "HorizontalLine");
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1.2f), topFrame.RectTransform, Anchor.CenterLeft), childAnchor: Anchor.BottomLeft, isHorizontal: true) { Stretch = true, RelativeSpacing = 0.05f };
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1.2f), topFrame.RectTransform, Anchor.CenterLeft), childAnchor: Anchor.BottomLeft, isHorizontal: true) // === INPUT SLOTS === //
{ inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null);
Stretch = true, inputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false };
RelativeSpacing = 0.045f
};
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null);
inputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null)
{
CanBeFocused = false
};
var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.75f), inputArea.RectTransform), style: null); // === ACTIVATE BUTTON === //
activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.65f), buttonContainer.RectTransform, Anchor.CenterLeft), var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.75f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft);
TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton") activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.65f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton")
{ {
TextBlock = { AutoScale = true }, TextBlock = { AutoScaleHorizontal = true },
OnClicked = ToggleActive OnClicked = ToggleActive
}; };
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform),
TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform), TextManager.Get("DeconstructorNoPower"), {
textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow") HoverColor = Color.Black,
{ IgnoreLayoutGroups = true,
HoverColor = Color.Black, Visible = false,
IgnoreLayoutGroups = true, CanBeFocused = false
Visible = false, };
CanBeFocused = false
};
// === OUTPUT AREA === //
var bottomFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null); var bottomFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null);
var paddedBottomLine = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), bottomFrame.RectTransform, Anchor.TopCenter), childAnchor: Anchor.CenterLeft, isHorizontal: true)
// === OUTPUT LABEL === //
var outputLabelArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.15f), bottomFrame.RectTransform, Anchor.TopCenter), childAnchor: Anchor.CenterLeft, isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.05f
};
var outputLabel = new GUITextBlock(new RectTransform(new Vector2(0f, 1.0f), outputLabelArea.RectTransform), TextManager.Get("uilabel.output"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
outputLabel.RectTransform.Resize(new Point((int) outputLabel.Font.MeasureString(outputLabel.Text).X, outputLabel.RectTransform.Rect.Height));
new GUIFrame(new RectTransform(Vector2.One, outputLabelArea.RectTransform), style: "HorizontalLine");
// === OUTPUT SLOTS === //
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.2f), bottomFrame.RectTransform, Anchor.CenterLeft), style: null);
}
public override bool Select(Character character)
{
// TODO, This works fine as of now but if GUI.PreventElementOverlap ever gets fixed this block of code may become obsolete or detrimental.
// Only do this if there's only one linked component. If you link more containers then may
// GUI.PreventElementOverlap have mercy on your HUD layout
if (item.linkedTo.Count(entity => entity is Item item && item.DisplaySideBySideWhenLinked) == 1)
{ {
Stretch = true, foreach (MapEntity linkedTo in item.linkedTo)
RelativeSpacing = 0.02f {
}; if (!(linkedTo is Item linkedItem)) continue;
var outputText = new GUITextBlock(new RectTransform(new Vector2(0f, 1.0f), paddedBottomLine.RectTransform), TextManager.Get("uilabel.output"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero }; if (!linkedItem.Components.Any()) continue;
new GUIFrame(new RectTransform(new Vector2(1f, 1.0f), paddedBottomLine.RectTransform), style: "HorizontalLine");
// Resize GUITextBlock width according to the text length var itemContainer = linkedItem.Components.First();
outputText.RectTransform.Resize(new Point((int)outputText.Font.MeasureString(outputText.Text).X, outputText.RectTransform.Rect.Height)); if (itemContainer == null) { continue; }
if (!itemContainer.Item.DisplaySideBySideWhenLinked) continue;
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.2f), bottomFrame.RectTransform, Anchor.CenterLeft), style: null); // how much spacing do we want between the components
var padding = (int) (8 * GUI.Scale);
// Move the linked container to the right and move the fabricator to the left
itemContainer.GuiFrame.RectTransform.AbsoluteOffset = new Point(GuiFrame.Rect.Width / -2 - padding, 0);
GuiFrame.RectTransform.AbsoluteOffset = new Point(itemContainer.GuiFrame.Rect.Width / 2 + padding, 0);
}
}
return base.Select(character);
} }
partial void OnItemLoadedProjSpecific() partial void OnItemLoadedProjSpecific()
@@ -59,7 +59,7 @@ namespace Barotrauma.Items.Components
string powerLabel = TextManager.Get("EngineForce"); string powerLabel = TextManager.Get("EngineForce");
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), sliderArea.RectTransform, Anchor.TopCenter), "", textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.Center) new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), sliderArea.RectTransform, Anchor.TopCenter), "", textColor: GUI.Style.TextColor, font: GUI.SubHeadingFont, textAlignment: Alignment.Center)
{ {
AutoScale = true, AutoScaleHorizontal = true,
TextGetter = () => { return TextManager.AddPunctuation(':', powerLabel, (int)(targetForce) + " %"); } TextGetter = () => { return TextManager.AddPunctuation(':', powerLabel, (int)(targetForce) + " %"); }
}; };
forceSlider = new GUIScrollBar(new RectTransform(new Vector2(0.95f, 0.45f), sliderArea.RectTransform, Anchor.Center), barSize: 0.1f, style: "DeviceSlider") forceSlider = new GUIScrollBar(new RectTransform(new Vector2(0.95f, 0.45f), sliderArea.RectTransform, Anchor.Center), barSize: 0.1f, style: "DeviceSlider")
@@ -5,6 +5,7 @@ using Microsoft.Xna.Framework.Graphics;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
namespace Barotrauma.Items.Components namespace Barotrauma.Items.Components
{ {
@@ -25,7 +26,6 @@ namespace Barotrauma.Items.Components
private GUIComponent outputSlot; private GUIComponent outputSlot;
private GUIComponent inputInventoryHolder, outputInventoryHolder; private GUIComponent inputInventoryHolder, outputInventoryHolder;
private GUICustomComponent inputInventoryOverlay, outputInventoryOverlay;
public FabricationRecipe SelectedItem public FabricationRecipe SelectedItem
{ {
@@ -41,95 +41,125 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific() partial void InitProjSpecific()
{ {
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter) CreateGUI();
GameMain.Instance.OnResolutionChanged += () =>
{
GuiFrame.ClearChildren();
CreateGUI();
OnItemLoadedProjSpecific();
};
}
private void CreateGUI()
{
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter);
// === LABEL === //
new GUITextBlock(new RectTransform(new Vector2(1f, 0.05f), paddedFrame.RectTransform), item.Name, font: GUI.SubHeadingFont)
{
TextAlignment = Alignment.Center,
AutoScaleVertical = true
};
var mainFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), paddedFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
{ {
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
var topFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.7f), paddedFrame.RectTransform), "InnerFrameDark"); // === TOP AREA ===
var topFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.65f), mainFrame.RectTransform), style: "InnerFrameDark");
var paddedItemFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), topFrame.RectTransform), style: null); // === ITEM LIST ===
var itemListFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), paddedItemFrame.RectTransform, Anchor.Center)) var itemListFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), topFrame.RectTransform), childAnchor: Anchor.Center);
{ var paddedItemFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), itemListFrame.RectTransform))
Stretch = true {
}; Stretch = true,
RelativeSpacing = 0.03f
};
var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedItemFrame.RectTransform), isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.03f,
UserData = "filterarea"
};
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), filterArea.RectTransform), TextManager.Get("serverlog.filter"), font: GUI.SubHeadingFont)
{
Padding = Vector4.Zero,
AutoScaleVertical = true
};
itemFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), createClearButton: true);
itemFilterBox.OnTextChanged += (textBox, text) =>
{
FilterEntities(text);
return true;
};
filterArea.RectTransform.MaxSize = new Point(int.MaxValue, itemFilterBox.Rect.Height);
var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), itemListFrame.RectTransform), isHorizontal: true) itemList = new GUIListBox(new RectTransform(new Vector2(1f, 0.9f), paddedItemFrame.RectTransform), style: null)
{ {
Stretch = true, OnSelected = (component, userdata) =>
RelativeSpacing = 0.02f, {
UserData = "filterarea" selectedItem = userdata as FabricationRecipe;
}; if (selectedItem != null) SelectItem(Character.Controlled, selectedItem);
return true;
}
};
new GUITextBlock(new RectTransform(new Vector2(0.2f, 0.5f), filterArea.RectTransform), TextManager.Get("serverlog.filter"), font: GUI.SubHeadingFont) // === SEPARATOR === //
{ new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), topFrame.RectTransform, Anchor.Center), style: "VerticalLine");
Padding = Vector4.Zero,
AutoScale = true
};
itemFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), createClearButton: true);
itemFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; };
itemList = new GUIListBox(new RectTransform(new Vector2(1f, 0.85f), itemListFrame.RectTransform), style: null) // === OUTPUT AREA === //
{ var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1f), topFrame.RectTransform, Anchor.TopRight), childAnchor: Anchor.Center);
OnSelected = (component, userdata) => var paddedOutputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), outputArea.RectTransform));
var outputTopArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5F), paddedOutputArea.RectTransform, Anchor.Center), isHorizontal: true);
// === OUTPUT SLOT === //
outputSlot = new GUIFrame(new RectTransform(new Vector2(0.4f, 1f), outputTopArea.RectTransform), style: null);
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.2f), outputSlot.RectTransform, Anchor.BottomCenter), style: null);
new GUICustomComponent(new RectTransform(Vector2.One, outputInventoryHolder.RectTransform), DrawOutputOverLay) { CanBeFocused = false };
// === DESCRIPTION === //
selectedItemFrame = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), outputTopArea.RectTransform), style: null);
// === REQUIREMENTS === //
selectedItemReqsFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedOutputArea.RectTransform), style: null);
// === BOTTOM AREA === //
var bottomFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.3f), mainFrame.RectTransform), style: null);
// === SEPARATOR === //
var separatorArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.15f), bottomFrame.RectTransform, Anchor.TopCenter), childAnchor: Anchor.CenterLeft, isHorizontal: true)
{ {
selectedItem = userdata as FabricationRecipe; Stretch = true,
if (selectedItem != null) { SelectItem(Character.Controlled, selectedItem); } RelativeSpacing = 0.03f
return true; };
} var inputLabel = new GUITextBlock(new RectTransform(Vector2.One, separatorArea.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
}; inputLabel.RectTransform.Resize(new Point((int) inputLabel.Font.MeasureString(inputLabel.Text).X, inputLabel.RectTransform.Rect.Height));
new GUIFrame(new RectTransform(Vector2.One, separatorArea.RectTransform), style: "HorizontalLine");
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), topFrame.RectTransform, Anchor.Center), style: "VerticalLine"); // === INPUT AREA === //
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1f), bottomFrame.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomLeft);
var paddedOutputFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 1f), topFrame.RectTransform, Anchor.TopRight), style: null); // === INPUT SLOTS === //
var outputArea = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), paddedOutputFrame.RectTransform, Anchor.Center), style: null); inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.8f, 1f), inputArea.RectTransform), style: null);
new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawInputOverLay) { CanBeFocused = false };
// TODO, take off the duct tape and figure out a proper way to do this \/
var scaledFrame = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.55f), outputArea.RectTransform), style: null);
outputSlot = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.5f), outputArea.RectTransform), style: null);
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1.1f, 1.5f), scaledFrame.RectTransform, Anchor.BottomCenter), style: null);
outputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, outputArea.RectTransform), DrawOutputOverLay) { CanBeFocused = false };
selectedItemFrame = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.5f), outputArea.RectTransform, Anchor.TopRight), style: null);
selectedItemReqsFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), outputArea.RectTransform, Anchor.BottomLeft), style: null);
var bottomFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.35f), paddedFrame.RectTransform), style: null);
var paddedLine = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), bottomFrame.RectTransform, Anchor.TopCenter), childAnchor: Anchor.CenterLeft, isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.02f
};
var inputText = new GUITextBlock(new RectTransform(new Vector2(0f, 1.0f), paddedLine.RectTransform), TextManager.Get("uilabel.input"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
new GUIFrame(new RectTransform(new Vector2(1f, 1.0f), paddedLine.RectTransform), style: "HorizontalLine");
// Resize GUITextBlock width according to the text length
inputText.RectTransform.Resize(new Point((int)inputText.Font.MeasureString(inputText.Text).X, inputText.RectTransform.Rect.Height));
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1f), bottomFrame.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomLeft);
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.8f, 1f), inputArea.RectTransform), style: null);
inputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawInputOverLay) { CanBeFocused = false };
// === ACTIVATE BUTTON === //
var buttonFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterRight);
activateButton = new GUIButton(new RectTransform(new Vector2(1f, 0.6f), buttonFrame.RectTransform),
TextManager.Get("FabricatorCreate"), style: "DeviceButton")
{
OnClicked = StartButtonClicked,
UserData = selectedItem,
Enabled = false
};
// === POWER WARNING === //
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform),
TextManager.Get("FabricatorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
{
HoverColor = Color.Black,
IgnoreLayoutGroups = true,
Visible = false,
CanBeFocused = false
};
CreateRecipes(); CreateRecipes();
var buttonFrame = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.8f), inputArea.RectTransform), style: null);
activateButton = new GUIButton(new RectTransform(new Vector2(1f, 0.6f), buttonFrame.RectTransform, Anchor.CenterRight),
TextManager.Get("FabricatorCreate"), style: "DeviceButton")
{
OnClicked = StartButtonClicked,
UserData = selectedItem,
Enabled = false
};
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform), TextManager.Get("FabricatorNoPower"),
textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
{
HoverColor = Color.Black,
IgnoreLayoutGroups = true,
Visible = false,
CanBeFocused = false
};
} }
partial void CreateRecipes() partial void CreateRecipes()
@@ -138,7 +168,7 @@ namespace Barotrauma.Items.Components
foreach (FabricationRecipe fi in fabricationRecipes) foreach (FabricationRecipe fi in fabricationRecipes)
{ {
GUIFrame frame = new GUIFrame(new RectTransform(new Point(itemList.Rect.Width, (int)(30 * GUI.yScale)), itemList.Content.RectTransform), style: null) var frame = new GUIFrame(new RectTransform(new Point(itemList.Rect.Width, (int)(40 * GUI.yScale)), itemList.Content.RectTransform), style: null)
{ {
UserData = fi, UserData = fi,
HoverColor = Color.Gold * 0.2f, HoverColor = Color.Gold * 0.2f,
@@ -146,22 +176,26 @@ namespace Barotrauma.Items.Components
ToolTip = fi.TargetItem.Description ToolTip = fi.TargetItem.Description
}; };
new GUITextBlock(new RectTransform(Vector2.Zero, frame.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point((int)(50 * GUI.xScale), 0) }, var container = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform),
fi.DisplayName) childAnchor: Anchor.CenterLeft, isHorizontal: true) { RelativeSpacing = 0.02f };
{
ToolTip = fi.TargetItem.Description
};
var itemIcon = fi.TargetItem.InventoryIcon ?? fi.TargetItem.sprite; var itemIcon = fi.TargetItem.InventoryIcon ?? fi.TargetItem.sprite;
if (itemIcon != null) if (itemIcon != null)
{ {
new GUIImage(new RectTransform(new Point((int)(30 * GUI.Scale)), frame.RectTransform, Anchor.CenterLeft) { AbsoluteOffset = new Point((int)(3 * GUI.xScale), 0) }, new GUIImage(new RectTransform(new Point(frame.Rect.Height,frame.Rect.Height), container.RectTransform),
itemIcon, scaleToFit: true) itemIcon, scaleToFit: true)
{ {
Color = fi.TargetItem.InventoryIconColor, Color = fi.TargetItem.InventoryIconColor,
ToolTip = fi.TargetItem.Description ToolTip = fi.TargetItem.Description
}; };
} }
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform), fi.DisplayName)
{
Padding = Vector4.Zero,
AutoScaleVertical = true,
ToolTip = fi.TargetItem.Description
};
} }
} }
@@ -175,6 +209,29 @@ namespace Barotrauma.Items.Components
partial void SelectProjSpecific(Character character) partial void SelectProjSpecific(Character character)
{ {
// TODO, This works fine as of now but if GUI.PreventElementOverlap ever gets fixed this block of code may become obsolete or detrimental.
// Only do this if there's only one linked component. If you link more containers then may
// GUI.PreventElementOverlap have mercy on your HUD layout
if (item.linkedTo.Count(entity => entity is Item item && item.DisplaySideBySideWhenLinked) == 1)
{
foreach (MapEntity linkedTo in item.linkedTo)
{
if (!(linkedTo is Item linkedItem)) continue;
if (!linkedItem.Components.Any()) continue;
var itemContainer = linkedItem.Components.First();
if (itemContainer == null) { continue; }
if (!itemContainer.Item.DisplaySideBySideWhenLinked) continue;
// how much spacing do we want between the components
var padding = (int) (8 * GUI.Scale);
// Move the linked container to the right and move the fabricator to the left
itemContainer.GuiFrame.RectTransform.AbsoluteOffset = new Point(GuiFrame.Rect.Width / -2 - padding, 0);
GuiFrame.RectTransform.AbsoluteOffset = new Point(itemContainer.GuiFrame.Rect.Width / 2 + padding, 0);
}
}
var nonItems = itemList.Content.Children.Where(c => !(c.UserData is FabricationRecipe)).ToList(); var nonItems = itemList.Content.Children.Where(c => !(c.UserData is FabricationRecipe)).ToList();
nonItems.ForEach(i => itemList.Content.RemoveChild(i)); nonItems.ForEach(i => itemList.Content.RemoveChild(i));
@@ -197,7 +254,7 @@ namespace Barotrauma.Items.Components
var sufficientSkillsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform), var sufficientSkillsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
TextManager.Get("fabricatorsufficientskills", returnNull: true) ?? "Sufficient skills to fabricate", textColor: GUI.Style.Green, font: GUI.SubHeadingFont) TextManager.Get("fabricatorsufficientskills", returnNull: true) ?? "Sufficient skills to fabricate", textColor: GUI.Style.Green, font: GUI.SubHeadingFont)
{ {
AutoScale = true, AutoScaleHorizontal = true,
CanBeFocused = false CanBeFocused = false
}; };
sufficientSkillsText.RectTransform.SetAsFirstChild(); sufficientSkillsText.RectTransform.SetAsFirstChild();
@@ -205,7 +262,7 @@ namespace Barotrauma.Items.Components
var insufficientSkillsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform), var insufficientSkillsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
TextManager.Get("fabricatorinsufficientskills", returnNull: true) ?? "Insufficient skills to fabricate", textColor: Color.Orange, font: GUI.SubHeadingFont) TextManager.Get("fabricatorinsufficientskills", returnNull: true) ?? "Insufficient skills to fabricate", textColor: Color.Orange, font: GUI.SubHeadingFont)
{ {
AutoScale = true, AutoScaleHorizontal = true,
CanBeFocused = false CanBeFocused = false
}; };
var firstinSufficient = itemList.Content.Children.FirstOrDefault(c => c.UserData is FabricationRecipe fabricableItem && DegreeOfSuccess(character, fabricableItem.RequiredSkills) < 0.5f); var firstinSufficient = itemList.Content.Children.FirstOrDefault(c => c.UserData is FabricationRecipe fabricableItem && DegreeOfSuccess(character, fabricableItem.RequiredSkills) < 0.5f);
@@ -361,7 +418,7 @@ namespace Barotrauma.Items.Components
selectedItemReqsFrame.ClearChildren(); selectedItemReqsFrame.ClearChildren();
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f }; var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
var paddedReqFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), selectedItemReqsFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f }; var paddedReqFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemReqsFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
/*var itemIcon = selectedItem.TargetItem.InventoryIcon ?? selectedItem.TargetItem.sprite; /*var itemIcon = selectedItem.TargetItem.InventoryIcon ?? selectedItem.TargetItem.sprite;
if (itemIcon != null) if (itemIcon != null)
@@ -375,7 +432,7 @@ namespace Barotrauma.Items.Components
var nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), var nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform),
selectedItem.TargetItem.Name, textAlignment: Alignment.CenterLeft, textColor: Color.Aqua, font: GUI.SubHeadingFont) selectedItem.TargetItem.Name, textAlignment: Alignment.CenterLeft, textColor: Color.Aqua, font: GUI.SubHeadingFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
nameBlock.Padding = new Vector4(0, nameBlock.Padding.Y, nameBlock.Padding.Z, nameBlock.Padding.W); nameBlock.Padding = new Vector4(0, nameBlock.Padding.Y, nameBlock.Padding.Z, nameBlock.Padding.W);
@@ -409,7 +466,7 @@ namespace Barotrauma.Items.Components
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform),
TextManager.Get("FabricatorRequiredSkills"), textColor: inadequateSkills.Any() ? GUI.Style.Red : GUI.Style.Green, font: GUI.SubHeadingFont) TextManager.Get("FabricatorRequiredSkills"), textColor: inadequateSkills.Any() ? GUI.Style.Red : GUI.Style.Green, font: GUI.SubHeadingFont)
{ {
AutoScale = true, AutoScaleHorizontal = true,
}; };
foreach (Skill skill in selectedItem.RequiredSkills) foreach (Skill skill in selectedItem.RequiredSkills)
{ {
@@ -427,7 +484,7 @@ namespace Barotrauma.Items.Components
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform),
TextManager.Get("FabricatorRequiredTime") , textColor: ToolBox.GradientLerp(degreeOfSuccess, GUI.Style.Red, Color.Yellow, GUI.Style.Green), font: GUI.SubHeadingFont) TextManager.Get("FabricatorRequiredTime") , textColor: ToolBox.GradientLerp(degreeOfSuccess, GUI.Style.Red, Color.Yellow, GUI.Style.Green), font: GUI.SubHeadingFont)
{ {
AutoScale = true, AutoScaleHorizontal = true,
}; };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), ToolBox.SecondsToReadableTime(requiredTime), new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), ToolBox.SecondsToReadableTime(requiredTime),
@@ -506,8 +563,10 @@ namespace Barotrauma.Items.Components
activateButton.Enabled = canBeFabricated; activateButton.Enabled = canBeFabricated;
} }
child.GetChild<GUITextBlock>().TextColor = Color.White * (canBeFabricated ? 1.0f : 0.5f); var childContainer = child.GetChild<GUILayoutGroup>();
child.GetChild<GUIImage>().Color = itemPrefab.TargetItem.InventoryIconColor * (canBeFabricated ? 1.0f : 0.5f);
childContainer.GetChild<GUITextBlock>().TextColor = Color.White * (canBeFabricated ? 1.0f : 0.5f);
childContainer.GetChild<GUIImage>().Color = itemPrefab.TargetItem.InventoryIconColor * (canBeFabricated ? 1.0f : 0.5f);
} }
} }
} }
@@ -26,6 +26,7 @@ namespace Barotrauma.Items.Components
noPowerTip = TextManager.Get("SteeringNoPowerTip"); noPowerTip = TextManager.Get("SteeringNoPowerTip");
GuiFrame.RectTransform.RelativeOffset = new Vector2(0.05f, 0.0f); GuiFrame.RectTransform.RelativeOffset = new Vector2(0.05f, 0.0f);
GuiFrame.CanBeFocused = true;
new GUICustomComponent(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset }, new GUICustomComponent(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset },
DrawHUDBack, null); DrawHUDBack, null);
submarineContainer = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), GuiFrame.RectTransform, Anchor.Center), style: null); submarineContainer = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), GuiFrame.RectTransform, Anchor.Center), style: null);
@@ -55,7 +55,7 @@ namespace Barotrauma.Items.Components
{ {
CanBeFocused = false CanBeFocused = false
}; };
powerLight.TextBlock.AutoScale = true; powerLight.TextBlock.AutoScaleHorizontal = true;
powerLight.TextBlock.OverrideTextColor(GUI.Style.TextColor); powerLight.TextBlock.OverrideTextColor(GUI.Style.TextColor);
PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.TopCenter) PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.TopCenter)
{ {
@@ -83,14 +83,14 @@ namespace Barotrauma.Items.Components
{ {
CanBeFocused = false CanBeFocused = false
}; };
autoControlIndicator.TextBlock.AutoScale = true; autoControlIndicator.TextBlock.AutoScaleHorizontal = true;
autoControlIndicator.TextBlock.OverrideTextColor(GUI.Style.TextColor); autoControlIndicator.TextBlock.OverrideTextColor(GUI.Style.TextColor);
var sliderArea = new GUIFrame(new RectTransform(new Vector2(1, 0.65f), rightArea.RectTransform, Anchor.BottomLeft), style: null); var sliderArea = new GUIFrame(new RectTransform(new Vector2(1, 0.65f), rightArea.RectTransform, Anchor.BottomLeft), style: null);
var pumpSpeedText = new GUITextBlock(new RectTransform(new Vector2(1, 0.3f), sliderArea.RectTransform, Anchor.TopLeft), "", var pumpSpeedText = new GUITextBlock(new RectTransform(new Vector2(1, 0.3f), sliderArea.RectTransform, Anchor.TopLeft), "",
textColor: GUI.Style.TextColor, textAlignment: Alignment.CenterLeft, wrap: false, font: GUI.SubHeadingFont) textColor: GUI.Style.TextColor, textAlignment: Alignment.CenterLeft, wrap: false, font: GUI.SubHeadingFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
string pumpSpeedStr = TextManager.Get("PumpSpeed"); string pumpSpeedStr = TextManager.Get("PumpSpeed");
pumpSpeedText.TextGetter = () => { return TextManager.AddPunctuation(':', pumpSpeedStr, (int)flowPercentage + " %"); }; pumpSpeedText.TextGetter = () => { return TextManager.AddPunctuation(':', pumpSpeedStr, (int)flowPercentage + " %"); };
@@ -75,7 +75,7 @@ namespace Barotrauma.Items.Components
graphLine = new Sprite(element.GetChildElement("graphline")?.GetChildElement("sprite")); graphLine = new Sprite(element.GetChildElement("graphline")?.GetChildElement("sprite"));
var paddedFrame = new GUILayoutGroup(new RectTransform( var paddedFrame = new GUILayoutGroup(new RectTransform(
GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin.Multiply(new Vector2(1.4f, 1.2f)), GuiFrame.RectTransform, Anchor.Center) GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center)
{ AbsoluteOffset = GUIStyle.ItemFrameOffset }, { AbsoluteOffset = GUIStyle.ItemFrameOffset },
isHorizontal: true) isHorizontal: true)
{ {
@@ -90,6 +90,7 @@ namespace Barotrauma.Items.Components
}; };
GUILayoutGroup columnRight = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), paddedFrame.RectTransform)) GUILayoutGroup columnRight = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), paddedFrame.RectTransform))
{ {
CanBeFocused = true,
RelativeSpacing = 0.012f, RelativeSpacing = 0.012f,
Stretch = true Stretch = true
}; };
@@ -104,7 +105,7 @@ namespace Barotrauma.Items.Components
RelativeOffset = new Vector2(-0.02f, 0) RelativeOffset = new Vector2(-0.02f, 0)
}, style: "ItemUI"); }, style: "ItemUI");
GUILayoutGroup inventoryContent = new GUILayoutGroup(new RectTransform(inventoryWindow.Rect.Size - GUIStyle.ItemFrameMargin.Multiply(0.75f), inventoryWindow.RectTransform, Anchor.Center) GUILayoutGroup inventoryContent = new GUILayoutGroup(new RectTransform(inventoryWindow.Rect.Size - GUIStyle.ItemFrameMargin, inventoryWindow.RectTransform, Anchor.Center)
{ AbsoluteOffset = GUIStyle.ItemFrameOffset }, { AbsoluteOffset = GUIStyle.ItemFrameOffset },
childAnchor: Anchor.TopCenter) childAnchor: Anchor.TopCenter)
{ {
@@ -126,6 +127,7 @@ namespace Barotrauma.Items.Components
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
Point maxIndicatorSize = new Point(int.MaxValue, (int)(50 * GUI.Scale)); Point maxIndicatorSize = new Point(int.MaxValue, (int)(50 * GUI.Scale));
criticalHeatWarning = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize }, criticalHeatWarning = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
TextManager.Get("ReactorWarningCriticalTemp"), font: GUI.SubHeadingFont, style: "IndicatorLightRed") TextManager.Get("ReactorWarningCriticalTemp"), font: GUI.SubHeadingFont, style: "IndicatorLightRed")
@@ -142,16 +144,14 @@ namespace Barotrauma.Items.Components
{ {
CanBeFocused = false CanBeFocused = false
}; };
criticalHeatWarning.TextBlock.OverrideTextColor(GUI.Style.TextColor); List<GUITickBox> indicatorLights = new List<GUITickBox>() { criticalHeatWarning, lowTemperatureWarning, criticalOutputWarning };
lowTemperatureWarning.TextBlock.OverrideTextColor(GUI.Style.TextColor); indicatorLights.ForEach(l => l.TextBlock.OverrideTextColor(GUI.Style.TextColor));
criticalOutputWarning.TextBlock.OverrideTextColor(GUI.Style.TextColor);
topLeftArea.Recalculate(); topLeftArea.Recalculate();
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), columnLeft.RectTransform), style: "HorizontalLine"); new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), columnLeft.RectTransform), style: "HorizontalLine");
float relativeYMargin = 0.02f; float relativeYMargin = 0.02f;
Vector2 relativeTextSize = new Vector2(0.8f, 0.1f); Vector2 relativeTextSize = new Vector2(0.9f, 0.2f);
Vector2 sliderSize = new Vector2(1.0f, 0.125f); Vector2 sliderSize = new Vector2(1.0f, 0.125f);
Vector2 meterSize = new Vector2(1, 1 - relativeTextSize.Y - relativeYMargin - sliderSize.Y - 0.1f); Vector2 meterSize = new Vector2(1, 1 - relativeTextSize.Y - relativeYMargin - sliderSize.Y - 0.1f);
@@ -162,7 +162,7 @@ namespace Barotrauma.Items.Components
var fissionRateTextBox = new GUITextBlock(new RectTransform(relativeTextSize, leftArea.RectTransform, Anchor.TopCenter), var fissionRateTextBox = new GUITextBlock(new RectTransform(relativeTextSize, leftArea.RectTransform, Anchor.TopCenter),
TextManager.Get("ReactorFissionRate"), textColor: GUI.Style.TextColor, textAlignment: Alignment.Center, font: GUI.SubHeadingFont) TextManager.Get("ReactorFissionRate"), textColor: GUI.Style.TextColor, textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
var fissionMeter = new GUICustomComponent(new RectTransform(meterSize, leftArea.RectTransform, Anchor.TopCenter) var fissionMeter = new GUICustomComponent(new RectTransform(meterSize, leftArea.RectTransform, Anchor.TopCenter)
{ {
@@ -176,7 +176,7 @@ namespace Barotrauma.Items.Components
var turbineOutputTextBox = new GUITextBlock(new RectTransform(relativeTextSize, rightArea.RectTransform, Anchor.TopCenter), var turbineOutputTextBox = new GUITextBlock(new RectTransform(relativeTextSize, rightArea.RectTransform, Anchor.TopCenter),
TextManager.Get("ReactorTurbineOutput"), textColor: GUI.Style.TextColor, textAlignment: Alignment.Center, font: GUI.SubHeadingFont) TextManager.Get("ReactorTurbineOutput"), textColor: GUI.Style.TextColor, textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
GUITextBlock.AutoScaleAndNormalize(turbineOutputTextBox, fissionRateTextBox); GUITextBlock.AutoScaleAndNormalize(turbineOutputTextBox, fissionRateTextBox);
@@ -248,11 +248,12 @@ namespace Barotrauma.Items.Components
Font = GUI.SubHeadingFont, Font = GUI.SubHeadingFont,
CanBeFocused = false CanBeFocused = false
}; };
b.TextBlock.Wrap = false;
warningButtons.Add(text, b); warningButtons.Add(text, b);
} }
upperButtons.Recalculate(); upperButtons.Recalculate();
lowerButtons.Recalculate(); lowerButtons.Recalculate();
//only wrap texts that consist of multiple words and are way too big to fit otherwise
warningButtons.Values.ForEach(b => b.TextBlock.Wrap = b.Text.Contains(' ') && b.TextBlock.TextSize.X > b.TextBlock.Rect.Width * 1.5f);
GUITextBlock.AutoScaleAndNormalize(warningButtons.Values.Select(b => b.TextBlock)); GUITextBlock.AutoScaleAndNormalize(warningButtons.Values.Select(b => b.TextBlock));
//---------------------------------------------------------- //----------------------------------------------------------
@@ -266,6 +267,7 @@ namespace Barotrauma.Items.Components
Stretch = true, Stretch = true,
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
topRightArea.RectTransform.MinSize = new Point(0, topLeftArea.Rect.Height);
topRightArea.RectTransform.MaxSize = new Point(int.MaxValue, topLeftArea.Rect.Height); topRightArea.RectTransform.MaxSize = new Point(int.MaxValue, topLeftArea.Rect.Height);
new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine"); new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine");
@@ -289,7 +291,7 @@ namespace Barotrauma.Items.Components
TextManager.Get("ReactorAutoTemp"), font: GUI.SubHeadingFont, style: "IndicatorLightYellow") TextManager.Get("ReactorAutoTemp"), font: GUI.SubHeadingFont, style: "IndicatorLightYellow")
{ {
ToolTip = TextManager.Get("ReactorTipAutoTemp"), ToolTip = TextManager.Get("ReactorTipAutoTemp"),
CanBeFocused = true, CanBeFocused = false,
Selected = AutoTemp Selected = AutoTemp
}; };
autoTempLight.RectTransform.MaxSize = new Point(int.MaxValue, criticalHeatWarning.Rect.Height); autoTempLight.RectTransform.MaxSize = new Point(int.MaxValue, criticalHeatWarning.Rect.Height);
@@ -300,13 +302,14 @@ namespace Barotrauma.Items.Components
// Power button // Power button
var powerArea = new GUIFrame(new RectTransform(new Vector2(0.4f, 1.0f), topRightArea.RectTransform), style: null); var powerArea = new GUIFrame(new RectTransform(new Vector2(0.4f, 1.0f), topRightArea.RectTransform), style: null);
var paddedPowerArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), powerArea.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.BothHeight), style: "PowerButtonFrame"); var paddedPowerArea = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), powerArea.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.BothHeight), style: "PowerButtonFrame");
powerLight = new GUITickBox(new RectTransform(new Vector2(0.87f, 0.2f), paddedPowerArea.RectTransform, Anchor.TopCenter, Pivot.Center), powerLight = new GUITickBox(new RectTransform(new Vector2(0.87f, 0.3f), paddedPowerArea.RectTransform, Anchor.TopCenter, Pivot.Center),
TextManager.Get("PowerLabel"), font: GUI.SubHeadingFont, style: "IndicatorLightPower") TextManager.Get("PowerLabel"), font: GUI.SubHeadingFont, style: "IndicatorLightPower")
{ {
CanBeFocused = false, CanBeFocused = false,
Selected = _powerOn Selected = _powerOn
}; };
powerLight.TextBlock.AutoScale = true; powerLight.TextBlock.Padding = new Vector4(5.0f, 0.0f, 0.0f, 0.0f);
powerLight.TextBlock.AutoScaleHorizontal = true;
powerLight.TextBlock.OverrideTextColor(GUI.Style.TextColor); powerLight.TextBlock.OverrideTextColor(GUI.Style.TextColor);
PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.BottomCenter) PowerButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.75f), paddedPowerArea.RectTransform, Anchor.BottomCenter)
{ {
@@ -324,16 +327,17 @@ namespace Barotrauma.Items.Components
topRightArea.Recalculate(); topRightArea.Recalculate();
autoTempLight.TextBlock.Wrap = true; autoTempLight.TextBlock.Wrap = true;
GUITextBlock.AutoScaleAndNormalize( indicatorLights.Add(autoTempLight);
criticalHeatWarning.TextBlock, lowTemperatureWarning.TextBlock, criticalOutputWarning.TextBlock, autoTempLight.TextBlock); GUITextBlock.AutoScaleAndNormalize(indicatorLights.Select(l => l.TextBlock));
// right bottom (graph area) ----------------------- // right bottom (graph area) -----------------------
new GUIFrame(new RectTransform(new Vector2(0.95f, 0.01f), columnRight.RectTransform), style: "HorizontalLine"); new GUIFrame(new RectTransform(new Vector2(0.95f, 0.01f), columnRight.RectTransform), style: "HorizontalLine");
var bottomRightArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), columnRight.RectTransform), isHorizontal: true) var bottomRightArea = new GUILayoutGroup(new RectTransform(Vector2.One, columnRight.RectTransform), isHorizontal: true)
{ {
Stretch = true, Stretch = true,
CanBeFocused = true,
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
@@ -347,7 +351,7 @@ namespace Barotrauma.Items.Components
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
relativeTextSize = new Vector2(1.0f, 0.0f); relativeTextSize = new Vector2(1.0f, 0.15f);
var loadText = new GUITextBlock(new RectTransform(relativeTextSize, graphArea.RectTransform), var loadText = new GUITextBlock(new RectTransform(relativeTextSize, graphArea.RectTransform),
"Load", textColor: loadColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft) "Load", textColor: loadColor, font: GUI.SubHeadingFont, textAlignment: Alignment.CenterLeft)
{ {
@@ -72,6 +72,10 @@ namespace Barotrauma.Items.Components
private readonly Color negativeColor = Color.Red; private readonly Color negativeColor = Color.Red;
private readonly Color markerColor = Color.Red; private readonly Color markerColor = Color.Red;
public static readonly Vector2 controlBoxSize = new Vector2(0.33f, 0.32f);
public static readonly Vector2 controlBoxOffset = new Vector2(0.025f, 0);
public static readonly float sonarAreaSize = 1.09f;
private static readonly Dictionary<BlipType, Color[]> blipColorGradient = new Dictionary<BlipType, Color[]>() private static readonly Dictionary<BlipType, Color[]> blipColorGradient = new Dictionary<BlipType, Color[]>()
{ {
{ {
@@ -132,29 +136,28 @@ namespace Barotrauma.Items.Components
} }
} }
CreateGUI(); CreateGUI();
GameMain.Instance.OnResolutionChanged += ResetLayout; GameMain.Instance.OnResolutionChanged += RecreateGUI;
// TODO: do we need to react on this?
GameMain.Config.OnHUDScaleChanged += ResetLayout;
} }
private void ResetLayout() private void RecreateGUI()
{ {
GuiFrame.RectTransform.Children.ForEachMod(c => c.Parent = null); GuiFrame.ClearChildren();
CreateGUI(); CreateGUI();
} }
private void CreateGUI() private void CreateGUI()
{ {
controlContainer = new GUIFrame(new RectTransform(new Vector2(controlContainerRelativeWidth, 0.32f), GuiFrame.RectTransform, Anchor.TopRight) bool isConnectedToSteering = item.GetComponent<Steering>() != null;
{ Vector2 size = isConnectedToSteering ? controlBoxSize : new Vector2(controlBoxSize.X * 2.0f, controlBoxSize.Y);
RelativeOffset = new Vector2(controlContainerRelativeOffset, 0)
}, "ItemUI");
controlContainer = new GUIFrame(new RectTransform(size, GuiFrame.RectTransform, Anchor.BottomRight, Pivot.BottomLeft), "ItemUI");
var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center) var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center)
{ {
AbsoluteOffset = GUIStyle.ItemFrameOffset AbsoluteOffset = GUIStyle.ItemFrameOffset
}, style: null); }, style: null);
var sonarModeArea = new GUIFrame(new RectTransform(new Vector2(1, 0.5f), paddedControlContainer.RectTransform, Anchor.TopCenter), style: null); // Based on the height difference to the steering control box so that the elements keep the same size
float extraHeight = 0.03f;
var sonarModeArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f + extraHeight), paddedControlContainer.RectTransform, Anchor.TopCenter), style: null);
SonarModeSwitch = new GUIButton(new RectTransform(new Vector2(0.2f, 1), sonarModeArea.RectTransform), string.Empty, style: "SwitchVertical") SonarModeSwitch = new GUIButton(new RectTransform(new Vector2(0.2f, 1), sonarModeArea.RectTransform), string.Empty, style: "SwitchVertical")
{ {
Selected = false, Selected = false,
@@ -192,13 +195,11 @@ namespace Barotrauma.Items.Components
passiveTickBox.TextBlock.OverrideTextColor(GUI.Style.TextColor); passiveTickBox.TextBlock.OverrideTextColor(GUI.Style.TextColor);
activeTickBox.TextBlock.OverrideTextColor(GUI.Style.TextColor); activeTickBox.TextBlock.OverrideTextColor(GUI.Style.TextColor);
var zoomContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.2f), paddedControlContainer.RectTransform, Anchor.TopCenter) var lowerArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f + extraHeight), paddedControlContainer.RectTransform, Anchor.BottomCenter), style: null);
{ var zoomContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.45f), lowerArea.RectTransform, Anchor.TopCenter), style: null);
RelativeOffset = new Vector2(0, sonarModeArea.RectTransform.RelativeSize.Y + 0.025f) var zoomText = new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.6f), zoomContainer.RectTransform, Anchor.CenterLeft),
}, style: null);
new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.6f), zoomContainer.RectTransform, Anchor.CenterLeft),
TextManager.Get("SonarZoom"), font: GUI.SubHeadingFont, textAlignment: Alignment.CenterRight); TextManager.Get("SonarZoom"), font: GUI.SubHeadingFont, textAlignment: Alignment.CenterRight);
zoomSlider = new GUIScrollBar(new RectTransform(new Vector2(0.6f, 0.8f), zoomContainer.RectTransform, Anchor.CenterLeft) zoomSlider = new GUIScrollBar(new RectTransform(new Vector2(0.5f, 0.8f), zoomContainer.RectTransform, Anchor.CenterLeft)
{ {
RelativeOffset = new Vector2(0.35f, 0) RelativeOffset = new Vector2(0.35f, 0)
}, barSize: 0.15f, isHorizontal: true, style: "DeviceSlider") }, barSize: 0.15f, isHorizontal: true, style: "DeviceSlider")
@@ -215,11 +216,9 @@ namespace Barotrauma.Items.Components
} }
}; };
var directionalModeFrame = new GUIFrame(new RectTransform(new Vector2(1, 0.2f), paddedControlContainer.RectTransform, Anchor.BottomCenter), style: null); new GUIFrame(new RectTransform(new Vector2(0.8f, 0.01f), paddedControlContainer.RectTransform, Anchor.Center), style: "HorizontalLine");
new GUIFrame(new RectTransform(new Vector2(0.9f, 0.01f), directionalModeFrame.RectTransform, Anchor.TopCenter, Pivot.BottomCenter)
{ var directionalModeFrame = new GUIFrame(new RectTransform(new Vector2(1, 0.45f), lowerArea.RectTransform, Anchor.BottomCenter), style: null);
RelativeOffset = new Vector2(0, -0.15f)
}, style: "HorizontalLine");
directionalModeSwitch = new GUIButton(new RectTransform(new Vector2(0.3f, 0.8f), directionalModeFrame.RectTransform, Anchor.CenterLeft), string.Empty, style: "SwitchHorizontal") directionalModeSwitch = new GUIButton(new RectTransform(new Vector2(0.3f, 0.8f), directionalModeFrame.RectTransform, Anchor.CenterLeft), string.Empty, style: "SwitchHorizontal")
{ {
OnClicked = (button, data) => OnClicked = (button, data) =>
@@ -241,14 +240,22 @@ namespace Barotrauma.Items.Components
GuiFrame.CanBeFocused = false; GuiFrame.CanBeFocused = false;
sonarView = new GUICustomComponent(new RectTransform(SonarAreaSize, GuiFrame.RectTransform, Anchor.CenterLeft), GUITextBlock.AutoScaleAndNormalize(passiveTickBox.TextBlock, activeTickBox.TextBlock, zoomText, directionalModeSwitchText);
(spriteBatch, guiCustomComponent) => { DrawSonar(spriteBatch, guiCustomComponent.Rect); }, null);
sonarView.RectTransform.SetAsFirstChild();
}
public static readonly float controlContainerRelativeWidth = 0.35f; sonarView = new GUICustomComponent(new RectTransform(Vector2.One * 0.7f, GuiFrame.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.BothHeight),
public static readonly float controlContainerRelativeOffset = 0.1f; (spriteBatch, guiCustomComponent) => { DrawSonar(spriteBatch, guiCustomComponent.Rect); }, null);
public static Vector2 SonarAreaSize => Vector2.One - new Vector2(controlContainerRelativeWidth + controlContainerRelativeOffset);
// Setup layout for nav terminal
if (isConnectedToSteering)
{
controlContainer.RectTransform.SetPosition(Anchor.TopLeft);
controlContainer.RectTransform.RelativeOffset = controlBoxOffset;
sonarView.RectTransform.ScaleBasis = ScaleBasis.Smallest;
sonarView.RectTransform.SetPosition(Anchor.CenterRight);
sonarView.RectTransform.Resize(Vector2.One * GUI.RelativeHorizontalAspectRatio * sonarAreaSize);
GUITextBlock.AutoScaleAndNormalize(passiveTickBox.TextBlock, activeTickBox.TextBlock, zoomText, directionalModeSwitchText);
}
}
private void SetPingDirection(Vector2 direction) private void SetPingDirection(Vector2 direction)
{ {
@@ -380,7 +387,6 @@ namespace Barotrauma.Items.Components
else if (transducerCenter.X > Level.Loaded.Size.X) else if (transducerCenter.X > Level.Loaded.Size.X)
{ {
outsideLevelFlow = -(transducerCenter.X - Level.Loaded.Size.X) * 0.001f; outsideLevelFlow = -(transducerCenter.X - Level.Loaded.Size.X) * 0.001f;
} }
if (Rand.Range(0.0f, 100.0f) < Math.Abs(outsideLevelFlow)) if (Rand.Range(0.0f, 100.0f) < Math.Abs(outsideLevelFlow))
@@ -103,16 +103,14 @@ namespace Barotrauma.Items.Components
} }
} }
CreateGUI(); CreateGUI();
GameMain.Instance.OnResolutionChanged += ResetGUI; GameMain.Instance.OnResolutionChanged += RecreateGUI;
// TODO: do we need to react on this?
GameMain.Config.OnHUDScaleChanged += ResetGUI;
} }
private void CreateGUI() private void CreateGUI()
{ {
controlContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.36f), GuiFrame.RectTransform, Anchor.CenterRight) controlContainer = new GUIFrame(new RectTransform(new Vector2(Sonar.controlBoxSize.X, Sonar.controlBoxSize.Y + 0.02f), GuiFrame.RectTransform, Anchor.CenterLeft)
{ {
RelativeOffset = new Vector2(Sonar.controlContainerRelativeOffset / 2, 0.01f) // Based on the relative size differende of the steering and the status windows RelativeOffset = new Vector2(0, 0) // The y offset should be based on the relative size difference of the steering and the status windows
}, "ItemUI"); }, "ItemUI");
var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center) var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center)
{ {
@@ -156,15 +154,18 @@ namespace Barotrauma.Items.Components
autopilotIndicator.TextBlock.OverrideTextColor(GUI.Style.TextColor); autopilotIndicator.TextBlock.OverrideTextColor(GUI.Style.TextColor);
GUITextBlock.AutoScaleAndNormalize(manualPilotIndicator.TextBlock, autopilotIndicator.TextBlock); GUITextBlock.AutoScaleAndNormalize(manualPilotIndicator.TextBlock, autopilotIndicator.TextBlock);
var autoPilotControls = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.6f), paddedControlContainer.RectTransform, Anchor.BottomRight), "OutlineFrame"); var autoPilotControls = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.6f), paddedControlContainer.RectTransform, Anchor.BottomCenter)
var paddedAutoPilotControls = new GUILayoutGroup(new RectTransform(new Vector2(0.9f), autoPilotControls.RectTransform, Anchor.Center)) {
RelativeOffset = new Vector2(0, 0.02f)
}, "OutlineFrame");
var paddedAutoPilotControls = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), autoPilotControls.RectTransform, Anchor.Center))
{ {
Stretch = true, Stretch = true,
RelativeSpacing = 0.03f, RelativeSpacing = 0.03f,
ChildAnchor = Anchor.TopCenter ChildAnchor = Anchor.TopLeft
}; };
maintainPosTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.2f), paddedAutoPilotControls.RectTransform), maintainPosTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.3f), paddedAutoPilotControls.RectTransform),
TextManager.Get("SteeringMaintainPos"), font: GUI.SmallFont, style: "GUIRadioButton") TextManager.Get("SteeringMaintainPos"), font: GUI.SmallFont, style: "GUIRadioButton")
{ {
Enabled = false, Enabled = false,
@@ -200,8 +201,8 @@ namespace Barotrauma.Items.Components
} }
}; };
levelStartTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.2f), paddedAutoPilotControls.RectTransform), levelStartTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.3f), paddedAutoPilotControls.RectTransform),
GameMain.GameSession?.StartLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 20), GameMain.GameSession?.StartLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.StartLocation.Name, 30),
font: GUI.SmallFont, style: "GUIRadioButton") font: GUI.SmallFont, style: "GUIRadioButton")
{ {
Enabled = false, Enabled = false,
@@ -227,8 +228,8 @@ namespace Barotrauma.Items.Components
} }
}; };
levelEndTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.2f), paddedAutoPilotControls.RectTransform), levelEndTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.3f), paddedAutoPilotControls.RectTransform),
GameMain.GameSession?.EndLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, 20), GameMain.GameSession?.EndLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, 30),
font: GUI.SmallFont, style: "GUIRadioButton") font: GUI.SmallFont, style: "GUIRadioButton")
{ {
Enabled = false, Enabled = false,
@@ -269,16 +270,16 @@ namespace Barotrauma.Items.Components
levelStartSelected ? Destination.LevelStart : Destination.LevelEnd); levelStartSelected ? Destination.LevelStart : Destination.LevelEnd);
// Status -> // Status ->
statusContainer = new GUIFrame(new RectTransform(new Vector2(0.33f, 0.3f), GuiFrame.RectTransform, Anchor.BottomRight) statusContainer = new GUIFrame(new RectTransform(Sonar.controlBoxSize, GuiFrame.RectTransform, Anchor.BottomLeft)
{ {
RelativeOffset = new Vector2(Sonar.controlContainerRelativeOffset, 0) RelativeOffset = Sonar.controlBoxOffset
}, "ItemUI"); }, "ItemUI");
var paddedStatusContainer = new GUIFrame(new RectTransform(statusContainer.Rect.Size - GUIStyle.ItemFrameMargin, statusContainer.RectTransform, Anchor.Center) var paddedStatusContainer = new GUIFrame(new RectTransform(statusContainer.Rect.Size - GUIStyle.ItemFrameMargin, statusContainer.RectTransform, Anchor.Center, isFixedSize: false)
{ {
AbsoluteOffset = GUIStyle.ItemFrameOffset AbsoluteOffset = GUIStyle.ItemFrameOffset
}, style: null); }, style: null);
var elements = GUI.CreateElements(3, new Vector2(1f, 0.323f), paddedStatusContainer.RectTransform, rt => new GUIFrame(rt, style: null), Anchor.TopCenter, relativeSpacing: 0.01f); var elements = GUI.CreateElements(3, new Vector2(1f, 0.333f), paddedStatusContainer.RectTransform, rt => new GUIFrame(rt, style: null), Anchor.TopCenter, relativeSpacing: 0.01f);
List<GUIComponent> leftElements = new List<GUIComponent>(), centerElements = new List<GUIComponent>(), rightElements = new List<GUIComponent>(); List<GUIComponent> leftElements = new List<GUIComponent>(), centerElements = new List<GUIComponent>(), rightElements = new List<GUIComponent>();
for (int i = 0; i < elements.Count; i++) for (int i = 0; i < elements.Count; i++)
{ {
@@ -288,9 +289,9 @@ namespace Barotrauma.Items.Components
RelativeSpacing = 0.01f, RelativeSpacing = 0.01f,
Stretch = true Stretch = true
}; };
var left = new GUIFrame(new RectTransform(new Vector2(0.5f, 1), group.RectTransform), style: null); var left = new GUIFrame(new RectTransform(new Vector2(0.45f, 1), group.RectTransform), style: null);
var center = new GUIFrame(new RectTransform(new Vector2(0.175f, 1), group.RectTransform), style: null); var center = new GUIFrame(new RectTransform(new Vector2(0.15f, 1), group.RectTransform), style: null);
var right = new GUIFrame(new RectTransform(new Vector2(0.325f, 0.8f), group.RectTransform), style: null); var right = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.8f), group.RectTransform), style: null);
leftElements.Add(left); leftElements.Add(left);
centerElements.Add(center); centerElements.Add(center);
rightElements.Add(right); rightElements.Add(right);
@@ -338,36 +339,15 @@ namespace Barotrauma.Items.Components
}; };
} }
GUITextBlock.AutoScaleAndNormalize(leftElements.SelectMany(e => e.GetAllChildren<GUITextBlock>())); GUITextBlock.AutoScaleAndNormalize(leftElements.SelectMany(e => e.GetAllChildren<GUITextBlock>()));
// TODO: center texts are too small on low resolutions
GUITextBlock.AutoScaleAndNormalize(centerElements.SelectMany(e => e.GetAllChildren<GUITextBlock>())); GUITextBlock.AutoScaleAndNormalize(centerElements.SelectMany(e => e.GetAllChildren<GUITextBlock>()));
GUITextBlock.AutoScaleAndNormalize(rightElements.SelectMany(e => e.GetAllChildren<GUITextBlock>())); GUITextBlock.AutoScaleAndNormalize(rightElements.SelectMany(e => e.GetAllChildren<GUITextBlock>()));
pressureWarningText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.25f), paddedStatusContainer.RectTransform), TextManager.Get("SteeringDepthWarning"), GUI.Style.Red)
{
Visible = false
};
tipContainer = new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.1f), GuiFrame.RectTransform, Anchor.BottomCenter, Pivot.TopCenter)
{
RelativeOffset = new Vector2(-0.2f, 0.0f)
}, "", font: GUI.Font, wrap: true, style: "GUIToolTip", textAlignment: Alignment.Center)
{
AutoScale = true
};
noPowerTip = TextManager.Get("SteeringNoPowerTip");
autoPilotMaintainPosTip = TextManager.Get("SteeringAutoPilotMaintainPosTip");
autoPilotLevelStartTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.StartLocation == null ? "Start" : GameMain.GameSession.StartLocation.Name);
autoPilotLevelEndTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.EndLocation == null ? "End" : GameMain.GameSession.EndLocation.Name);
//docking interface ---------------------------------------------------- //docking interface ----------------------------------------------------
float dockingButtonSize = 1.1f; float dockingButtonSize = 1.1f;
float elementScale = 0.6f; float elementScale = 0.6f;
dockingContainer = new GUIFrame(new RectTransform(new Point(160).Multiply(GUI.Scale * dockingButtonSize), GuiFrame.RectTransform, Anchor.BottomRight) dockingContainer = new GUIFrame(new RectTransform(new Point(160).Multiply(GUI.Scale * dockingButtonSize), GuiFrame.RectTransform, Anchor.BottomLeft)
{ {
RelativeOffset = new Vector2(Sonar.controlContainerRelativeOffset + 0.05f, -0.05f) RelativeOffset = new Vector2(Sonar.controlBoxOffset.X + 0.15f, -0.1f)
}, style: null); }, style: null);
dockText = TextManager.Get("label.navterminaldock", fallBackTag: "captain.dock"); dockText = TextManager.Get("label.navterminaldock", fallBackTag: "captain.dock");
@@ -416,16 +396,32 @@ namespace Barotrauma.Items.Components
UserData = -Vector2.UnitY UserData = -Vector2.UnitY
}; };
steerArea = new GUICustomComponent(new RectTransform(Sonar.SonarAreaSize, GuiFrame.RectTransform, Anchor.CenterLeft), // Sonar area
steerArea = new GUICustomComponent(new RectTransform(Vector2.One * GUI.RelativeHorizontalAspectRatio * Sonar.sonarAreaSize, GuiFrame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest),
(spriteBatch, guiCustomComponent) => { DrawHUD(spriteBatch, guiCustomComponent.Rect); }, null); (spriteBatch, guiCustomComponent) => { DrawHUD(spriteBatch, guiCustomComponent.Rect); }, null);
steerArea.RectTransform.SetAsFirstChild();
steerRadius = steerArea.Rect.Width / 2; steerRadius = steerArea.Rect.Width / 2;
// Tooltip/helper text
pressureWarningText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.25f), paddedStatusContainer.RectTransform), TextManager.Get("SteeringDepthWarning"), GUI.Style.Red)
{
Visible = false
};
tipContainer = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.1f), steerArea.RectTransform, Anchor.BottomCenter, Pivot.TopCenter)
, "", font: GUI.Font, wrap: true, style: "GUIToolTip", textAlignment: Alignment.Center)
{
AutoScaleHorizontal = true
};
noPowerTip = TextManager.Get("SteeringNoPowerTip");
autoPilotMaintainPosTip = TextManager.Get("SteeringAutoPilotMaintainPosTip");
autoPilotLevelStartTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.StartLocation == null ? "Start" : GameMain.GameSession.StartLocation.Name);
autoPilotLevelEndTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.EndLocation == null ? "End" : GameMain.GameSession.EndLocation.Name);
} }
private void RecreateGUI()
private void ResetGUI()
{ {
GuiFrame.RectTransform.Children.ForEachMod(c => c.Parent = null); GuiFrame.ClearChildren();
CreateGUI(); CreateGUI();
} }
@@ -706,7 +702,7 @@ namespace Barotrauma.Items.Components
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; } if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
if (PlayerInput.KeyDown(InputType.Up)) { input += Vector2.UnitY; } if (PlayerInput.KeyDown(InputType.Up)) { input += Vector2.UnitY; }
if (PlayerInput.KeyDown(InputType.Down)) { input -= Vector2.UnitY; } if (PlayerInput.KeyDown(InputType.Down)) { input -= Vector2.UnitY; }
if (PlayerInput.KeyDown(Keys.LeftShift)) if (PlayerInput.KeyDown(InputType.Run))
{ {
SteeringInput += input * deltaTime * 200; SteeringInput += input * deltaTime * 200;
inputCumulation = 0; inputCumulation = 0;
@@ -99,7 +99,7 @@ namespace Barotrauma.Items.Components
}; };
GUITextBlock.AutoScaleAndNormalize(powerLabel, loadLabel); GUITextBlock.AutoScaleAndNormalize(powerLabel, loadLabel);
GUITextBlock.AutoScaleAndNormalize(powerText, loadText); GUITextBlock.AutoScaleAndNormalize(true, true, powerText, loadText);
GUITextBlock.AutoScaleAndNormalize(kw1, kw2); GUITextBlock.AutoScaleAndNormalize(kw1, kw2);
} }
@@ -184,7 +184,7 @@ namespace Barotrauma.Items.Components
x = (int)(x + width / 2 - step * (panel.DisconnectedWires.Count() - 1) / 2); x = (int)(x + width / 2 - step * (panel.DisconnectedWires.Count() - 1) / 2);
foreach (Wire wire in panel.DisconnectedWires) foreach (Wire wire in panel.DisconnectedWires)
{ {
if (wire == DraggingConnected && mouseInRect) { continue; } if (wire == DraggingConnected && !mouseInRect) { continue; }
Connection recipient = wire.OtherConnection(null); Connection recipient = wire.OtherConnection(null);
string label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})"; string label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
@@ -197,7 +197,10 @@ namespace Barotrauma.Items.Components
//stop dragging a wire item if the cursor is within any connection panel //stop dragging a wire item if the cursor is within any connection panel
//(so we don't drop the item when dropping the wire on a connection) //(so we don't drop the item when dropping the wire on a connection)
if (mouseInRect || GUI.MouseOn?.UserData is ConnectionPanel) { Inventory.draggingItem = null; } if (mouseInRect || (GUI.MouseOn?.UserData is ConnectionPanel && GUI.MouseOn.MouseRect.Contains(PlayerInput.MousePosition)))
{
Inventory.draggingItem = null;
}
} }
private void DrawConnection(SpriteBatch spriteBatch, ConnectionPanel panel, Vector2 position, Vector2 labelPos, Vector2 scale) private void DrawConnection(SpriteBatch spriteBatch, ConnectionPanel panel, Vector2 position, Vector2 labelPos, Vector2 scale)
@@ -10,33 +10,52 @@ namespace Barotrauma.Items.Components
{ {
partial class CustomInterface partial class CustomInterface
{ {
private List<GUIComponent> uiElements = new List<GUIComponent>(); private readonly List<GUIComponent> uiElements = new List<GUIComponent>();
private GUILayoutGroup uiElementContainer; private GUILayoutGroup uiElementContainer;
private Point ElementMaxSize => new Point(uiElementContainer.Rect.Width, (int)(60 * GUI.yScale));
partial void InitProjSpecific(XElement element) partial void InitProjSpecific(XElement element)
{
CreateGUI();
GameMain.Instance.OnResolutionChanged += RecreateGUI;
}
private void RecreateGUI()
{
GuiFrame.ClearChildren();
CreateGUI();
}
private void CreateGUI()
{ {
uiElements.Clear(); uiElements.Clear();
var visibleElements = customInterfaceElementList.Where(ciElement => !string.IsNullOrEmpty(ciElement.Label)); var visibleElements = customInterfaceElementList.Where(ciElement => !string.IsNullOrEmpty(ciElement.Label));
uiElementContainer = new GUILayoutGroup(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center)
uiElementContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.75f, 0.65f), GuiFrame.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.025f) }, {
AbsoluteOffset = GUIStyle.ItemFrameOffset
},
childAnchor: customInterfaceElementList.Count > 1 ? Anchor.TopCenter : Anchor.Center) childAnchor: customInterfaceElementList.Count > 1 ? Anchor.TopCenter : Anchor.Center)
{ {
RelativeSpacing = 0.05f, RelativeSpacing = 0.05f,
Stretch = visibleElements.Count() > 2 Stretch = visibleElements.Count() > 2,
}; };
float elementSize = Math.Min(1.0f / visibleElements.Count(), 0.5f); float elementSize = Math.Min(1.0f / visibleElements.Count(), 1);
var textBlocks = new List<GUITextBlock>();
foreach (CustomInterfaceElement ciElement in visibleElements) foreach (CustomInterfaceElement ciElement in visibleElements)
{ {
if (ciElement.ContinuousSignal) if (ciElement.ContinuousSignal)
{ {
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementSize), uiElementContainer.RectTransform), var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementSize), uiElementContainer.RectTransform)
{
MaxSize = ElementMaxSize
},
TextManager.Get(ciElement.Label, returnNull: true) ?? ciElement.Label) TextManager.Get(ciElement.Label, returnNull: true) ?? ciElement.Label)
{ {
UserData = ciElement UserData = ciElement
}; };
tickBox.TextBlock.AutoScale = true; textBlocks.Add(tickBox.TextBlock);
tickBox.OnSelected += (tBox) => tickBox.OnSelected += (tBox) =>
{ {
if (GameMain.Client == null) if (GameMain.Client == null)
@@ -61,7 +80,7 @@ namespace Barotrauma.Items.Components
{ {
UserData = ciElement UserData = ciElement
}; };
btn.TextBlock.AutoScale = true; textBlocks.Add(btn.TextBlock);
btn.OnClicked += (_, userdata) => btn.OnClicked += (_, userdata) =>
{ {
if (GameMain.Client == null) if (GameMain.Client == null)
@@ -77,11 +96,12 @@ namespace Barotrauma.Items.Components
//reset size restrictions set by the Style to make sure the elements can fit the interface //reset size restrictions set by the Style to make sure the elements can fit the interface
btn.RectTransform.MinSize = btn.Frame.RectTransform.MinSize = new Point(0, 0); btn.RectTransform.MinSize = btn.Frame.RectTransform.MinSize = new Point(0, 0);
btn.RectTransform.MaxSize = btn.Frame.RectTransform.MaxSize = new Point(int.MaxValue, int.MaxValue); btn.RectTransform.MaxSize = btn.Frame.RectTransform.MaxSize = ElementMaxSize;
btn.TextBlock.Wrap = true; btn.TextBlock.Wrap = true;
uiElements.Add(btn); uiElements.Add(btn);
} }
GUITextBlock.AutoScaleAndNormalize(textBlocks);
} }
} }
@@ -128,12 +148,8 @@ namespace Barotrauma.Items.Components
int visibleElementCount = 0; int visibleElementCount = 0;
foreach (var uiElement in uiElements) foreach (var uiElement in uiElements)
{ {
CustomInterfaceElement element = uiElement.UserData as CustomInterfaceElement; if (!(uiElement.UserData is CustomInterfaceElement element)) { continue; }
if (element == null) { continue; } bool visible = Screen.Selected == GameMain.SubEditorScreen || element.StatusEffects.Any() || (element.Connection != null && element.Connection.Wires.Any(w => w != null));
bool visible =
Screen.Selected == GameMain.SubEditorScreen ||
element.StatusEffects.Any() ||
(element.Connection != null && element.Connection.Wires.Any(w => w != null));
if (visible) { visibleElementCount++; } if (visible) { visibleElementCount++; }
if (uiElement.Visible != visible) if (uiElement.Visible != visible)
{ {
@@ -146,11 +162,12 @@ namespace Barotrauma.Items.Components
{ {
uiElementContainer.Stretch = visibleElementCount > 2; uiElementContainer.Stretch = visibleElementCount > 2;
uiElementContainer.ChildAnchor = visibleElementCount > 1 ? Anchor.TopCenter : Anchor.Center; uiElementContainer.ChildAnchor = visibleElementCount > 1 ? Anchor.TopCenter : Anchor.Center;
float elementSize = Math.Min(1.0f / visibleElementCount, 0.5f); float elementSize = Math.Min(1.0f / visibleElementCount, 1);
foreach (var uiElement in uiElements) foreach (var uiElement in uiElements)
{ {
uiElement.RectTransform.RelativeSize = new Vector2(1.0f, elementSize); uiElement.RectTransform.RelativeSize = new Vector2(1.0f, elementSize);
} }
GuiFrame.Visible = visibleElementCount > 0;
} }
} }
@@ -94,8 +94,8 @@ namespace Barotrauma.Items.Components
Submarine sub = item.Submarine; Submarine sub = item.Submarine;
if (IsActive && sub == null) // currently being rewired, we need to get the sub from the connections in case the wire has been taken outside if (IsActive && sub == null) // currently being rewired, we need to get the sub from the connections in case the wire has been taken outside
{ {
if (connections[0] != null && connections[0].Item.Submarine != null) sub = connections[0].Item.Submarine; if (connections[0] != null && connections[0].Item.Submarine != null) { sub = connections[0].Item.Submarine; }
if (connections[1] != null && connections[1].Item.Submarine != null) sub = connections[1].Item.Submarine; if (connections[1] != null && connections[1].Item.Submarine != null) { sub = connections[1].Item.Submarine; }
} }
if (sub != null) if (sub != null)
@@ -253,11 +253,15 @@ namespace Barotrauma.Items.Components
{ {
MapEntity.DisableSelect = true; MapEntity.DisableSelect = true;
Submarine sub = null; Submarine sub = draggingWire.item.Submarine;
if (draggingWire.connections[0] != null && draggingWire.connections[0].Item.Submarine != null) sub = draggingWire.connections[0].Item.Submarine; if (draggingWire.connections[0] != null && draggingWire.connections[0].Item.Submarine != null) sub = draggingWire.connections[0].Item.Submarine;
if (draggingWire.connections[1] != null && draggingWire.connections[1].Item.Submarine != null) sub = draggingWire.connections[1].Item.Submarine; if (draggingWire.connections[1] != null && draggingWire.connections[1].Item.Submarine != null) sub = draggingWire.connections[1].Item.Submarine;
Vector2 nodeWorldPos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition) - sub.HiddenSubPosition - sub.Position;// Nodes[(int)selectedNodeIndex]; Vector2 nodeWorldPos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
if (sub != null)
{
nodeWorldPos = nodeWorldPos - sub.HiddenSubPosition - sub.Position;
}
if (selectedNodeIndex.HasValue) if (selectedNodeIndex.HasValue)
{ {
@@ -352,7 +356,7 @@ namespace Barotrauma.Items.Components
foreach (Wire w in wires) foreach (Wire w in wires)
{ {
Vector2 mousePos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition); Vector2 mousePos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
if (w.item.Submarine != null) mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition); if (w.item.Submarine != null) { mousePos -= (w.item.Submarine.Position + w.item.Submarine.HiddenSubPosition); }
int highlightedNode = w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out float dist); int highlightedNode = w.GetClosestNodeIndex(mousePos, highlighted == null ? nodeSelectDist : closestDist, out float dist);
if (highlightedNode > -1) if (highlightedNode > -1)
@@ -131,10 +131,9 @@ namespace Barotrauma
protected float prevHUDScale = GUI.Scale; protected float prevHUDScale = GUI.Scale;
protected Point prevScreenResolution; protected Point prevScreenResolution;
protected static Sprite slotSpriteHorizontal, slotSpriteVertical, slotSpriteRound, slotHotkeySprite; protected static Sprite slotHotkeySprite;
public static Sprite SlotSpriteSmall; public static Sprite SlotSpriteSmall;
public static Sprite EquipIndicator, EquipIndicatorHighlight; public static Sprite EquipIndicator, EquipIndicatorHighlight;
public static Sprite DropIndicator, DropIndicatorHighlight;
public static Inventory DraggingInventory; public static Inventory DraggingInventory;
public Rectangle BackgroundFrame { get; protected set; } public Rectangle BackgroundFrame { get; protected set; }
@@ -291,7 +290,8 @@ namespace Barotrauma
int rows = (int)Math.Ceiling((double)capacity / slotsPerRow); int rows = (int)Math.Ceiling((double)capacity / slotsPerRow);
int columns = Math.Min(slotsPerRow, capacity); int columns = Math.Min(slotsPerRow, capacity);
Vector2 spacing = new Vector2(10 * UIScale, (10 + EquipIndicator.size.Y) * UIScale); Vector2 spacing = new Vector2(5.0f * UIScale);
spacing.Y += (this is CharacterInventory) ? EquipIndicator.size.Y * UIScale : ContainedIndicatorHeight;
Vector2 rectSize = new Vector2(60.0f * UIScale); Vector2 rectSize = new Vector2(60.0f * UIScale);
padding = new Vector4(spacing.X, spacing.Y, spacing.X, spacing.X); padding = new Vector4(spacing.X, spacing.Y, spacing.X, spacing.X);
@@ -534,88 +534,77 @@ namespace Barotrauma
int itemCapacity = subInventory.Items.Length; int itemCapacity = subInventory.Items.Length;
var slot = slots[slotIndex]; var slot = slots[slotIndex];
int dir = slot.SubInventoryDir; int dir = slot.SubInventoryDir;
if (itemCapacity == 1 && false) Rectangle subRect = slot.Rect;
Vector2 spacing = new Vector2(10 * UIScale, (10 + EquipIndicator.size.Y) * UIScale);
int columns = (int)Math.Max(Math.Floor(Math.Sqrt(itemCapacity)), 1);
while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f)
{ {
Point slotSize = (slotSpriteRound.size * UIScale).ToPoint(); columns++;
subInventory.slots[0].Rect =
new Rectangle(slot.Rect.Center.X - slotSize.X / 2, dir > 0 ? slot.Rect.Bottom + 5 : slot.EquipButtonRect.Bottom + 5, slotSize.X, slotSize.Y);
subInventory.slots[0].InteractRect = subInventory.slots[0].Rect;
subInventory.slots[0].DrawOffset = slot.DrawOffset;
} }
else
int width = (int)(subRect.Width * columns + spacing.X * (columns - 1));
int startX = slot.Rect.Center.X - (int)(width / 2.0f);
int startY = dir < 0 ?
slot.EquipButtonRect.Y - subRect.Height - (int)(35 * UIScale) :
slot.EquipButtonRect.Bottom + (int)(10 * UIScale);
if (canMove)
{ {
Rectangle subRect = slot.Rect; startX += subInventory.savedPosition.X - subInventory.originalPos.X;
Vector2 spacing = new Vector2(10 * UIScale, (10 + EquipIndicator.size.Y) * UIScale); startY += subInventory.savedPosition.Y - subInventory.originalPos.Y;
int columns = (int)Math.Max(Math.Floor(Math.Sqrt(itemCapacity)), 1);
while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f)
{
columns++;
}
int width = (int)(subRect.Width * columns + spacing.X * (columns - 1));
int startX = slot.Rect.Center.X - (int)(width / 2.0f);
int startY = dir < 0 ?
slot.EquipButtonRect.Y - subRect.Height - (int)(35 * UIScale) :
slot.EquipButtonRect.Bottom + (int)(10 * UIScale);
if (canMove)
{
startX += subInventory.savedPosition.X - subInventory.originalPos.X;
startY += subInventory.savedPosition.Y - subInventory.originalPos.Y;
}
float totalHeight = itemCapacity / columns * (subRect.Height + spacing.Y);
int padding = (int)(20 * UIScale);
//prevent the inventory from extending outside the left side of the screen
startX = Math.Max(startX, padding);
//same for the right side of the screen
startX -= Math.Max(startX + width - GameMain.GraphicsWidth + padding, 0);
//prevent the inventory from extending outside the top of the screen
startY = Math.Max(startY, (int)totalHeight - padding / 2);
//same for the bottom side of the screen
startY -= Math.Max(startY - GameMain.GraphicsHeight + padding * 2 + (canMove ? (int)(movableFrameRectHeight * UIScale) : 0), 0);
subRect.X = startX;
subRect.Y = startY;
subInventory.OpenState = subInventory.HideTimer >= 0.5f ?
Math.Min(subInventory.OpenState + deltaTime * 8.0f, 1.0f) :
Math.Max(subInventory.OpenState - deltaTime * 5.0f, 0.0f);
for (int i = 0; i < itemCapacity; i++)
{
subInventory.slots[i].Rect = subRect;
subInventory.slots[i].Rect.Location += new Point(0, (int)totalHeight * -dir);
subInventory.slots[i].DrawOffset = Vector2.SmoothStep(new Vector2(0, -50 * dir), new Vector2(0, totalHeight * dir), subInventory.OpenState);
subInventory.slots[i].InteractRect = new Rectangle(
(int)(subInventory.slots[i].Rect.X - spacing.X / 2 - 1), (int)(subInventory.slots[i].Rect.Y - spacing.Y / 2 - 1),
(int)(subInventory.slots[i].Rect.Width + spacing.X + 2), (int)(subInventory.slots[i].Rect.Height + spacing.Y + 2));
if ((i + 1) % columns == 0)
{
subRect.X = startX;
subRect.Y += subRect.Height * dir;
subRect.Y += (int)(spacing.Y * dir);
}
else
{
subRect.X = (int)(subInventory.slots[i].Rect.Right + spacing.X);
}
}
if (canMove)
{
subInventory.movableFrameRect.X = subRect.X - (int)spacing.X;
subInventory.movableFrameRect.Y = subRect.Y + (int)(spacing.Y);
}
slots[slotIndex].State = GUIComponent.ComponentState.Hover;
} }
float totalHeight = itemCapacity / columns * (subRect.Height + spacing.Y);
int padding = (int)(20 * UIScale);
//prevent the inventory from extending outside the left side of the screen
startX = Math.Max(startX, padding);
//same for the right side of the screen
startX -= Math.Max(startX + width - GameMain.GraphicsWidth + padding, 0);
//prevent the inventory from extending outside the top of the screen
startY = Math.Max(startY, (int)totalHeight - padding / 2);
//same for the bottom side of the screen
startY -= Math.Max(startY - GameMain.GraphicsHeight + padding * 2 + (canMove ? (int)(movableFrameRectHeight * UIScale) : 0), 0);
subRect.X = startX;
subRect.Y = startY;
subInventory.OpenState = subInventory.HideTimer >= 0.5f ?
Math.Min(subInventory.OpenState + deltaTime * 8.0f, 1.0f) :
Math.Max(subInventory.OpenState - deltaTime * 5.0f, 0.0f);
for (int i = 0; i < itemCapacity; i++)
{
subInventory.slots[i].Rect = subRect;
subInventory.slots[i].Rect.Location += new Point(0, (int)totalHeight * -dir);
subInventory.slots[i].DrawOffset = Vector2.SmoothStep(new Vector2(0, -50 * dir), new Vector2(0, totalHeight * dir), subInventory.OpenState);
subInventory.slots[i].InteractRect = new Rectangle(
(int)(subInventory.slots[i].Rect.X - spacing.X / 2 - 1), (int)(subInventory.slots[i].Rect.Y - spacing.Y / 2 - 1),
(int)(subInventory.slots[i].Rect.Width + spacing.X + 2), (int)(subInventory.slots[i].Rect.Height + spacing.Y + 2));
if ((i + 1) % columns == 0)
{
subRect.X = startX;
subRect.Y += subRect.Height * dir;
subRect.Y += (int)(spacing.Y * dir);
}
else
{
subRect.X = (int)(subInventory.slots[i].Rect.Right + spacing.X);
}
}
if (canMove)
{
subInventory.movableFrameRect.X = subRect.X - (int)spacing.X;
subInventory.movableFrameRect.Y = subRect.Y + (int)(spacing.Y);
}
slots[slotIndex].State = GUIComponent.ComponentState.Hover;
subInventory.isSubInventory = true; subInventory.isSubInventory = true;
subInventory.Update(deltaTime, cam, true); subInventory.Update(deltaTime, cam, true);
} }
@@ -1168,10 +1157,14 @@ namespace Barotrauma
if (itemContainer.ContainedStateIndicator?.Texture == null) if (itemContainer.ContainedStateIndicator?.Texture == null)
{ {
containedIndicatorArea.Inflate(0, -2); containedIndicatorArea.Inflate(0, -2);
GUI.DrawRectangle(spriteBatch, containedIndicatorArea, Color.DarkGray * 0.9f, true); GUI.DrawRectangle(spriteBatch, containedIndicatorArea, Color.Gray * 0.9f, true);
GUI.DrawRectangle(spriteBatch, GUI.DrawRectangle(spriteBatch,
new Rectangle(containedIndicatorArea.X, containedIndicatorArea.Y, (int)(containedIndicatorArea.Width * containedState), containedIndicatorArea.Height), new Rectangle(containedIndicatorArea.X, containedIndicatorArea.Y, (int)(containedIndicatorArea.Width * containedState), containedIndicatorArea.Height),
Color.Lerp(GUI.Style.Red, GUI.Style.Green, containedState) * 0.8f, true); ToolBox.GradientLerp(containedState, Color.Red, Color.Orange, Color.LightGreen) * 0.8f, true);
GUI.DrawLine(spriteBatch,
new Vector2(containedIndicatorArea.X + (int)(containedIndicatorArea.Width * containedState), containedIndicatorArea.Y),
new Vector2(containedIndicatorArea.X + (int)(containedIndicatorArea.Width * containedState), containedIndicatorArea.Bottom),
Color.Black * 0.8f);
} }
else else
{ {
@@ -1186,12 +1179,12 @@ namespace Barotrauma
} }
indicatorSprite.Draw(spriteBatch, containedIndicatorArea.Center.ToVector2(), indicatorSprite.Draw(spriteBatch, containedIndicatorArea.Center.ToVector2(),
(inventory != null && inventory.Locked) ? Color.DarkGray * 0.5f : Color.DarkGray * 0.9f, (inventory != null && inventory.Locked) ? Color.Gray * 0.5f : Color.Gray * 0.9f,
origin: indicatorSprite.size / 2, origin: indicatorSprite.size / 2,
rotate: 0.0f, rotate: 0.0f,
scale: indicatorScale); scale: indicatorScale);
Color indicatorColor = ToolBox.GradientLerp(containedState, GUI.Style.Red, GUI.Style.Orange, GUI.Style.Green); Color indicatorColor = ToolBox.GradientLerp(containedState, Color.Red, Color.Orange, Color.LightGreen);
if (inventory != null && inventory.Locked) { indicatorColor *= 0.5f; } if (inventory != null && inventory.Locked) { indicatorColor *= 0.5f; }
spriteBatch.Draw(indicatorSprite.Texture, containedIndicatorArea.Center.ToVector2(), spriteBatch.Draw(indicatorSprite.Texture, containedIndicatorArea.Center.ToVector2(),
@@ -1201,6 +1194,14 @@ namespace Barotrauma
origin: indicatorSprite.size / 2, origin: indicatorSprite.size / 2,
scale: indicatorScale, scale: indicatorScale,
effects: SpriteEffects.None, layerDepth: 0.0f); effects: SpriteEffects.None, layerDepth: 0.0f);
spriteBatch.Draw(indicatorSprite.Texture, containedIndicatorArea.Center.ToVector2(),
sourceRectangle: new Rectangle(indicatorSprite.SourceRect.X - 1 + (int)(indicatorSprite.SourceRect.Width * containedState), indicatorSprite.SourceRect.Y, Math.Max((int)Math.Ceiling(1 / indicatorScale), 2), indicatorSprite.SourceRect.Height),
color: Color.Black,
rotation: 0.0f,
origin: new Vector2(indicatorSprite.size.X * (0.5f - containedState), indicatorSprite.size.Y * 0.5f),
scale: indicatorScale,
effects: SpriteEffects.None, layerDepth: 0.0f);
} }
} }
} }
@@ -1296,6 +1297,10 @@ namespace Barotrauma
// 2. We've received all the events created before the update was written (otherwise we may not yet know about some items the server has spawned in the inventory) // 2. We've received all the events created before the update was written (otherwise we may not yet know about some items the server has spawned in the inventory)
(GameMain.Client != null && (GameMain.Client.MidRoundSyncing || NetIdUtils.IdMoreRecent(lastEventID, GameMain.Client.EntityEventManager.LastReceivedID)))) (GameMain.Client != null && (GameMain.Client.MidRoundSyncing || NetIdUtils.IdMoreRecent(lastEventID, GameMain.Client.EntityEventManager.LastReceivedID))))
{ {
if (GameMain.GameSession == null || Level.Loaded == null)
{
yield return CoroutineStatus.Success;
}
syncItemsDelay = Math.Max((float)(syncItemsDelay - Timing.Step), 0.0f); syncItemsDelay = Math.Max((float)(syncItemsDelay - Timing.Step), 0.0f);
yield return CoroutineStatus.Running; yield return CoroutineStatus.Running;
} }
@@ -44,6 +44,11 @@ namespace Barotrauma
get { return activeSprite; } get { return activeSprite; }
} }
public override bool DrawOverWater
{
get { return base.DrawOverWater || (GetComponent<Wire>() != null && IsSelected); }
}
private GUITextBlock itemInUseWarning; private GUITextBlock itemInUseWarning;
private GUITextBlock ItemInUseWarning private GUITextBlock ItemInUseWarning
{ {
@@ -523,8 +528,8 @@ namespace Barotrauma
if (Linkable) if (Linkable)
{ {
var linkText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, heightScaled)), TextManager.Get("HoldToLink"), font: GUI.SmallFont); var linkText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, heightScaled), isFixedSize: true), TextManager.Get("HoldToLink"), font: GUI.SmallFont);
var itemsText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, heightScaled)), TextManager.Get("AllowedLinks"), font: GUI.SmallFont); var itemsText = new GUITextBlock(new RectTransform(new Point(editingHUD.Rect.Width, heightScaled), isFixedSize: true), TextManager.Get("AllowedLinks"), font: GUI.SmallFont);
string allowedItems = AllowedLinks.None() ? TextManager.Get("None") :string.Join(", ", AllowedLinks); string allowedItems = AllowedLinks.None() ? TextManager.Get("None") :string.Join(", ", AllowedLinks);
itemsText.Text = TextManager.AddPunctuation(':', itemsText.Text, allowedItems); itemsText.Text = TextManager.AddPunctuation(':', itemsText.Text, allowedItems);
itemEditor.AddCustomContent(linkText, 1); itemEditor.AddCustomContent(linkText, 1);
@@ -535,7 +540,8 @@ namespace Barotrauma
var buttonContainer = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, heightScaled)), isHorizontal: true) var buttonContainer = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, heightScaled)), isHorizontal: true)
{ {
Stretch = true, Stretch = true,
RelativeSpacing = 0.02f RelativeSpacing = 0.02f,
CanBeFocused = true
}; };
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"), style: "GUIButtonSmall") new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"), style: "GUIButtonSmall")
{ {
@@ -575,6 +581,7 @@ namespace Barotrauma
} }
}; };
buttonContainer.RectTransform.MinSize = new Point(0, buttonContainer.RectTransform.Children.Max(c => c.MinSize.Y)); buttonContainer.RectTransform.MinSize = new Point(0, buttonContainer.RectTransform.Children.Max(c => c.MinSize.Y));
buttonContainer.RectTransform.IsFixedSize = true;
itemEditor.AddCustomContent(buttonContainer, itemEditor.ContentCount); itemEditor.AddCustomContent(buttonContainer, itemEditor.ContentCount);
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Select(b => ((GUIButton)b).TextBlock)); GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Select(b => ((GUIButton)b).TextBlock));
} }
@@ -615,17 +622,20 @@ namespace Barotrauma
foreach (RelatedItem relatedItem in requiredItems) foreach (RelatedItem relatedItem in requiredItems)
{ {
//TODO: add to localization
var textBlock = new GUITextBlock(new RectTransform(new Point(listBox.Content.Rect.Width, heightScaled)), var textBlock = new GUITextBlock(new RectTransform(new Point(listBox.Content.Rect.Width, heightScaled)),
relatedItem.Type.ToString() + " required", font: GUI.SmallFont) relatedItem.Type.ToString() + " required", font: GUI.SmallFont)
{ {
Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f) Padding = new Vector4(10.0f, 0.0f, 10.0f, 0.0f)
}; };
textBlock.RectTransform.IsFixedSize = true;
componentEditor.AddCustomContent(textBlock, 1); componentEditor.AddCustomContent(textBlock, 1);
GUITextBox namesBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), textBlock.RectTransform, Anchor.CenterRight)) GUITextBox namesBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), textBlock.RectTransform, Anchor.CenterRight))
{ {
Font = GUI.SmallFont, Font = GUI.SmallFont,
Text = relatedItem.JoinedIdentifiers Text = relatedItem.JoinedIdentifiers,
OverflowClip = true
}; };
textBlock.RectTransform.Resize(new Point(textBlock.Rect.Width, namesBox.RectTransform.MinSize.Y)); textBlock.RectTransform.Resize(new Point(textBlock.Rect.Width, namesBox.RectTransform.MinSize.Y));
@@ -710,11 +720,11 @@ namespace Barotrauma
HUDLayoutSettings.ChatBoxArea.Width + disallowedPadding, HUDLayoutSettings.ChatBoxArea.Height)); HUDLayoutSettings.ChatBoxArea.Width + disallowedPadding, HUDLayoutSettings.ChatBoxArea.Height));
} }
//GUI.PreventElementOverlap(elementsToMove, disallowedAreas, GUI.PreventElementOverlap(elementsToMove, disallowedAreas,
// new Rectangle( new Rectangle(
// 0, 20, 0, 20,
// GameMain.GraphicsWidth, GameMain.GraphicsWidth,
// HUDLayoutSettings.InventoryTopY > 0 ? HUDLayoutSettings.InventoryTopY - 40 : GameMain.GraphicsHeight - 80)); HUDLayoutSettings.InventoryTopY > 0 ? HUDLayoutSettings.InventoryTopY - 40 : GameMain.GraphicsHeight - 80));
foreach (ItemComponent ic in activeHUDs) foreach (ItemComponent ic in activeHUDs)
{ {
@@ -761,7 +771,8 @@ namespace Barotrauma
List<ItemComponent> maxPriorityHUDs = new List<ItemComponent>(); List<ItemComponent> maxPriorityHUDs = new List<ItemComponent>();
foreach (ItemComponent ic in activeComponents) foreach (ItemComponent ic in activeComponents)
{ {
if (ic.CanBeSelected && ic.HudPriority > 0 && ic.ShouldDrawHUD(character) && if (ic.HudPriority > 0 && ic.ShouldDrawHUD(character) &&
(ic.CanBeSelected || character.HasEquippedItem(this)) &&
(maxPriorityHUDs.Count == 0 || ic.HudPriority >= maxPriorityHUDs[0].HudPriority)) (maxPriorityHUDs.Count == 0 || ic.HudPriority >= maxPriorityHUDs[0].HudPriority))
{ {
if (maxPriorityHUDs.Count > 0 && ic.HudPriority > maxPriorityHUDs[0].HudPriority) maxPriorityHUDs.Clear(); if (maxPriorityHUDs.Count > 0 && ic.HudPriority > maxPriorityHUDs[0].HudPriority) maxPriorityHUDs.Clear();
@@ -777,7 +788,10 @@ namespace Barotrauma
{ {
foreach (ItemComponent ic in activeComponents) foreach (ItemComponent ic in activeComponents)
{ {
if (ic.CanBeSelected && ic.ShouldDrawHUD(character)) activeHUDs.Add(ic); if ((ic.CanBeSelected || character.HasEquippedItem(this)) && ic.ShouldDrawHUD(character))
{
activeHUDs.Add(ic);
}
} }
} }
@@ -867,11 +881,6 @@ namespace Barotrauma
} }
public override void AddToGUIUpdateList() public override void AddToGUIUpdateList()
{
AddToGUIUpdateList(addLinkedHUDs: true);
}
private void AddToGUIUpdateList(bool addLinkedHUDs)
{ {
if (Screen.Selected is SubEditorScreen) if (Screen.Selected is SubEditorScreen)
{ {
@@ -1,4 +1,5 @@
using Barotrauma.Items.Components; using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
@@ -733,9 +734,10 @@ namespace Barotrauma
var clones = mapEntityList.Except(prevEntities).ToList(); var clones = mapEntityList.Except(prevEntities).ToList();
var nonWireClones = clones.Where(c => !(c is Item item) || item.GetComponent<Wire>() == null);
Vector2 center = Vector2.Zero; Vector2 center = Vector2.Zero;
clones.ForEach(c => center += c.WorldPosition); nonWireClones.ForEach(c => center += c.WorldPosition);
center = Submarine.VectorToWorldGrid(center / clones.Count); center = Submarine.VectorToWorldGrid(center / nonWireClones.Count());
Vector2 moveAmount = Submarine.VectorToWorldGrid(position - center); Vector2 moveAmount = Submarine.VectorToWorldGrid(position - center);
@@ -785,8 +787,8 @@ namespace Barotrauma
else else
{ {
editingHUD.RectTransform.SetPosition(Anchor.TopRight); editingHUD.RectTransform.SetPosition(Anchor.TopRight);
editingHUD.RectTransform.RelativeOffset = new Vector2(0.0f, (HUDLayoutSettings.InventoryAreaUpper.Bottom + 10.0f) / (editingHUD.RectTransform.Parent ?? GUI.Canvas).Rect.Height); editingHUD.RectTransform.RelativeOffset = new Vector2(0.0f, (HUDLayoutSettings.CrewArea.Bottom + 10.0f) / (editingHUD.RectTransform.Parent ?? GUI.Canvas).Rect.Height);
maxHeight = HUDLayoutSettings.InventoryAreaLower.Bottom - HUDLayoutSettings.InventoryAreaLower.Y - 10; maxHeight = HUDLayoutSettings.InventoryAreaLower.Y - HUDLayoutSettings.CrewArea.Bottom - 10;
} }
var listBox = editingHUD.GetChild<GUIListBox>(); var listBox = editingHUD.GetChild<GUIListBox>();
@@ -883,6 +885,7 @@ namespace Barotrauma
{ {
rectMemento.Store(Rect); rectMemento.Store(Rect);
resizing = false; resizing = false;
Resized?.Invoke(rect);
} }
} }
} }
@@ -122,8 +122,9 @@ namespace Barotrauma
return true; return true;
} }
}; };
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Where(c => c is GUIButton).Select(b => ((GUIButton)b).TextBlock));
buttonContainer.RectTransform.Resize(new Point(buttonContainer.Rect.Width, buttonContainer.RectTransform.Children.Max(c => c.MinSize.Y))); buttonContainer.RectTransform.Resize(new Point(buttonContainer.Rect.Width, buttonContainer.RectTransform.Children.Max(c => c.MinSize.Y)));
buttonContainer.RectTransform.IsFixedSize = true;
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Where(c => c is GUIButton).Select(b => ((GUIButton)b).TextBlock));
editor.AddCustomContent(buttonContainer, editor.ContentCount); editor.AddCustomContent(buttonContainer, editor.ContentCount);
PositionEditingHUD(); PositionEditingHUD();
@@ -2423,20 +2423,42 @@ namespace Barotrauma.Networking
//because tab is used for autocompleting console commands //because tab is used for autocompleting console commands
if (msgBox != null) if (msgBox != null)
{ {
if ((PlayerInput.KeyHit(InputType.Chat) || PlayerInput.KeyHit(InputType.RadioChat)) && if (GUI.KeyboardDispatcher.Subscriber == null)
GUI.KeyboardDispatcher.Subscriber == null)
{ {
if (msgBox.Selected) bool chatKeyHit = PlayerInput.KeyHit(InputType.Chat);
bool radioKeyHit = PlayerInput.KeyHit(InputType.RadioChat);
if (chatKeyHit || radioKeyHit)
{ {
msgBox.Text = ""; if (msgBox.Selected)
msgBox.Deselect();
}
else
{
msgBox.Select();
if (Screen.Selected == GameMain.GameScreen && PlayerInput.KeyHit(InputType.RadioChat))
{ {
msgBox.Text = "r; "; msgBox.Text = "";
msgBox.Deselect();
}
else
{
if (Screen.Selected == GameMain.GameScreen)
{
if (chatKeyHit)
{
msgBox.AddToGUIUpdateList();
ChatBox.GUIFrame.Flash(Color.DarkGreen, 0.5f);
ChatBox.ToggleOpen = true;
}
if (radioKeyHit)
{
msgBox.AddToGUIUpdateList();
ChatBox.GUIFrame.Flash(Color.YellowGreen, 0.5f);
ChatBox.ToggleOpen = true;
if (!msgBox.Text.StartsWith(ChatBox.RadioChatString))
{
msgBox.Text = ChatBox.RadioChatString;
}
}
}
msgBox.Select(msgBox.Text.Length);
} }
} }
} }
@@ -326,7 +326,7 @@ namespace Barotrauma.Networking
return true; return true;
} }
}; };
workshopBtn.TextBlock.AutoScale = true; workshopBtn.TextBlock.AutoScaleHorizontal = true;
} }
} }
@@ -1383,6 +1383,7 @@ namespace Barotrauma.Steam
if (!task.IsCompleted) if (!task.IsCompleted)
{ {
cancelTokenSource.Cancel(); cancelTokenSource.Cancel();
task.Wait();
} }
return task.Status == TaskStatus.RanToCompletion; return task.Status == TaskStatus.RanToCompletion;
@@ -152,7 +152,7 @@ namespace Barotrauma.Particles
} }
} }
[Editable(0.0f, 10000.0f), Serialize(0.0f, false, description: "Drag applied to the particle when it's moving through water.")] [Editable(0.0f, 10000.0f), Serialize(0.0f, false, description: "Radius of the particle's collider. Only has an effect if UseCollision is set to true.")]
public float CollisionRadius { get; private set; } public float CollisionRadius { get; private set; }
[Editable, Serialize(false, false, description: "Does the particle collide with the walls of the submarine and the level.")] [Editable, Serialize(false, false, description: "Does the particle collide with the walls of the submarine and the level.")]
@@ -78,7 +78,7 @@ namespace Barotrauma
OnClicked = (btn, userdata) => { SelectTab(Tab.Map); return true; } OnClicked = (btn, userdata) => { SelectTab(Tab.Map); return true; }
}; };
outpostBtn.TextBlock.Font = GUI.LargeFont; outpostBtn.TextBlock.Font = GUI.LargeFont;
outpostBtn.TextBlock.AutoScale = true; outpostBtn.TextBlock.AutoScaleHorizontal = true;
var tabButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.4f), topPanelContent.RectTransform, Anchor.BottomLeft), isHorizontal: true); var tabButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.4f), topPanelContent.RectTransform, Anchor.BottomLeft), isHorizontal: true);
@@ -161,7 +161,7 @@ namespace Barotrauma
{ {
UserData = "mycrew", UserData = "mycrew",
CanBeFocused = false, CanBeFocused = false,
AutoScale = true AutoScaleHorizontal = true
}; };
if (campaign is SinglePlayerCampaign) if (campaign is SinglePlayerCampaign)
{ {
@@ -170,7 +170,7 @@ namespace Barotrauma
{ {
UserData = "hire", UserData = "hire",
CanBeFocused = false, CanBeFocused = false,
AutoScale = true AutoScaleHorizontal = true
}; };
} }
@@ -210,6 +210,7 @@ namespace Barotrauma
searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform), createClearButton: true); searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform), createClearButton: true);
searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; }; searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; }; searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
searchBox.OnTextChanged += (textBox, text) => { FilterStoreItems(null, text); return true; };
var storeItemLists = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), storeContent.RectTransform), isHorizontal: true) var storeItemLists = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), storeContent.RectTransform), isHorizontal: true)
{ {
@@ -256,7 +257,7 @@ namespace Barotrauma
TextManager.Get("MapEntityCategory." + category), textAlignment: Alignment.Center, textColor: categoryButton.TextColor) TextManager.Get("MapEntityCategory." + category), textAlignment: Alignment.Center, textColor: categoryButton.TextColor)
{ {
Padding = Vector4.Zero, Padding = Vector4.Zero,
AutoScale = true, AutoScaleHorizontal = true,
Color = Color.Transparent, Color = Color.Transparent,
HoverColor = Color.Transparent, HoverColor = Color.Transparent,
PressedColor = Color.Transparent, PressedColor = Color.Transparent,
@@ -454,7 +455,7 @@ namespace Barotrauma
textAlignment: Alignment.Center, font: GUI.LargeFont, style: "GUISlopedHeader") textAlignment: Alignment.Center, font: GUI.LargeFont, style: "GUISlopedHeader")
{ {
UserData = "missionlabel", UserData = "missionlabel",
AutoScale = true AutoScaleHorizontal = true
}; };
var missionPanelContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), missionPanel.RectTransform, Anchor.Center)) var missionPanelContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), missionPanel.RectTransform, Anchor.Center))
{ {
@@ -468,10 +469,11 @@ namespace Barotrauma
Stretch = true Stretch = true
}; };
selectedMissionInfo = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.25f), missionPanel.RectTransform, Anchor.BottomRight, Pivot.TopRight) selectedMissionInfo = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.25f), missionPanel.RectTransform, Anchor.BottomRight, Pivot.TopRight)
{ MinSize = new Point(0, (int)(250 * GUI.Scale)) }) { MinSize = new Point(0, (int)(150 * GUI.Scale)) })
{ {
Visible = false Visible = false
}; };
selectedMissionInfo.RectTransform.MaxSize = new Point(int.MaxValue, selectedMissionInfo.Rect.Height * 2);
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), selectedMissionInfo.RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.9f) new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), selectedMissionInfo.RectTransform, Anchor.Center), style: "OuterGlow", color: Color.Black * 0.9f)
{ {
UserData = "outerglow", UserData = "outerglow",
@@ -676,7 +678,7 @@ namespace Barotrauma
var container = selectedLocationInfo; var container = selectedLocationInfo;
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), location.Name, font: GUI.LargeFont) new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), location.Name, font: GUI.LargeFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), location.Type.Name, font: GUI.SubHeadingFont); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), location.Type.Name, font: GUI.SubHeadingFont);
@@ -686,7 +688,7 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), TextManager.Get("SelectMission"), font: GUI.SubHeadingFont) new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), TextManager.Get("SelectMission"), font: GUI.SubHeadingFont)
{ {
AutoScale = true AutoScaleHorizontal = true
}; };
var missionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), container.RectTransform), style: "InnerFrame"); var missionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), container.RectTransform), style: "InnerFrame");
@@ -784,13 +786,13 @@ namespace Barotrauma
selectedMissionInfo.ClearChildren(); selectedMissionInfo.ClearChildren();
var container = selectedMissionInfo.Content; var container = selectedMissionInfo.Content;
selectedMissionInfo.Visible = selectedMission != null; selectedMissionInfo.Visible = selectedMission != null;
selectedMissionInfo.Spacing = 10; selectedMissionInfo.Spacing = (int)(10 * GUI.Scale);
if (selectedMission == null) { return; } if (selectedMission == null) { return; }
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform),
selectedMission.Name, font: GUI.LargeFont) selectedMission.Name, font: GUI.LargeFont)
{ {
AutoScale = true, AutoScaleHorizontal = true,
CanBeFocused = false CanBeFocused = false
}; };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform), new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform),
@@ -804,6 +806,12 @@ namespace Barotrauma
CanBeFocused = false CanBeFocused = false
}; };
//scale down mission info box if it's much taller than the text
float missionInfoHeight = selectedMissionInfo.Content.Children.Sum(c => c.Rect.Height + selectedMissionInfo.Spacing);
selectedMissionInfo.Content.Children.ForEach(c => c.RectTransform.IsFixedSize = true);
selectedMissionInfo.RectTransform.Resize(new Point(selectedMissionInfo.Rect.Width, (int)(missionInfoHeight + 15 * GUI.Scale)));
selectedMissionInfo.UpdateScrollBarSize();
if (StartButton != null) if (StartButton != null)
{ {
StartButton.Enabled = true; StartButton.Enabled = true;
@@ -1897,7 +1897,7 @@ namespace Barotrauma.CharacterEditor
} }
// Create the areas // Create the areas
rightArea = new GUILayoutGroup(new RectTransform(new Vector2(0.15f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.CenterRight), childAnchor: Anchor.BottomRight) rightArea = new GUILayoutGroup(new RectTransform(new Vector2(0.15f, 1.0f), parent: Frame.RectTransform, anchor: Anchor.CenterRight), childAnchor: Anchor.BottomRight)
{ {
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
@@ -1917,6 +1917,14 @@ namespace Barotrauma.CharacterEditor
CreateFileEditPanel(); CreateFileEditPanel();
CreateOptionsPanel(toggleSize); CreateOptionsPanel(toggleSize);
CreateCharacterSelectionPanel(); CreateCharacterSelectionPanel();
if (rightArea.RectTransform.Children.Sum(c => c.Rect.Height) > GameMain.GraphicsHeight)
{
fileEditPanel.GetAllChildren().Where(c => c is GUIButton).ForEach(b => b.RectTransform.MinSize = ((GUIButton)b).Frame.RectTransform.MinSize = b.RectTransform.MinSize.Multiply(new Vector2(1.0f, 0.75f)));
fileEditPanel.RectTransform.MinSize = new Point(0, (int)(fileEditPanel.GetChild<GUILayoutGroup>().RectTransform.Children.Sum(c => c.Rect.Height) / innerScale.Y));
optionsPanel.GetAllChildren().Where(c => c is GUITickBox).ForEach(t => t.RectTransform.MinSize = t.RectTransform.MinSize.Multiply(new Vector2(1.0f, 0.75f)));
optionsPanel.RectTransform.MinSize = new Point(0, (int)(optionsPanel.GetChild<GUILayoutGroup>().RectTransform.Children.Sum(c => c.Rect.Height) / innerScale.Y));
rightArea.Recalculate();
}
CreateButtonsPanel(); CreateButtonsPanel();
CreateModesPanel(toggleSize); CreateModesPanel(toggleSize);
@@ -2686,14 +2694,14 @@ namespace Barotrauma.CharacterEditor
} }
var charButtons = new GUIFrame(new RectTransform(new Vector2(1, 0.25f), parent: content.RectTransform, anchor: Anchor.BottomLeft), style: null); var charButtons = new GUIFrame(new RectTransform(new Vector2(1, 0.25f), parent: content.RectTransform, anchor: Anchor.BottomLeft), style: null);
var prevCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopLeft), GetCharacterEditorTranslation("PreviousCharacter")); var prevCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopLeft), GetCharacterEditorTranslation("PreviousCharacter"));
prevCharacterButton.TextBlock.AutoScale = true; prevCharacterButton.TextBlock.AutoScaleHorizontal = true;
prevCharacterButton.OnClicked += (b, obj) => prevCharacterButton.OnClicked += (b, obj) =>
{ {
SpawnCharacter(GetPreviousConfigFile()); SpawnCharacter(GetPreviousConfigFile());
return true; return true;
}; };
var nextCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("NextCharacter")); var nextCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("NextCharacter"));
prevCharacterButton.TextBlock.AutoScale = true; prevCharacterButton.TextBlock.AutoScaleHorizontal = true;
nextCharacterButton.OnClicked += (b, obj) => nextCharacterButton.OnClicked += (b, obj) =>
{ {
SpawnCharacter(GetNextConfigFile()); SpawnCharacter(GetNextConfigFile());
@@ -3151,7 +3159,6 @@ namespace Barotrauma.CharacterEditor
public ToggleButton(RectTransform rectT, Direction dir) public ToggleButton(RectTransform rectT, Direction dir)
{ {
rectT.MaxSize = new Point(int.MaxValue, (int)(100 * GUI.Scale));
toggleButton = new GUIButton(rectT, style: "UIToggleButton") toggleButton = new GUIButton(rectT, style: "UIToggleButton")
{ {
OnClicked = (button, data) => OnClicked = (button, data) =>
@@ -157,7 +157,7 @@ namespace Barotrauma
//(= the background texture that's revealed when a wall is destroyed) into the background render target //(= the background texture that's revealed when a wall is destroyed) into the background render target
//These will be visible through the LOS effect. //These will be visible through the LOS effect.
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
Submarine.DrawBack(spriteBatch, false, e => e is Structure s); Submarine.DrawBack(spriteBatch, false, e => e is Structure s && (e.SpriteDepth >= 0.9f || s.Prefab.BackgroundSprite != null));
spriteBatch.End(); spriteBatch.End();
graphics.SetRenderTarget(null); graphics.SetRenderTarget(null);
@@ -201,7 +201,7 @@ namespace Barotrauma
spriteBatch.End(); spriteBatch.End();
//Draw the rest of the structures, characters and front structures //Draw the rest of the structures, characters and front structures
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, cam.Transform);
Submarine.DrawBack(spriteBatch, false, s => !(s is Structure)); Submarine.DrawBack(spriteBatch, false, e => !(e is Structure) || e.SpriteDepth < 0.9f);
foreach (Character c in Character.CharacterList) foreach (Character c in Character.CharacterList)
{ {
if (c.AnimController.Limbs.Any(l => l.DeformSprite != null) || !c.IsVisible) { continue; } if (c.AnimController.Limbs.Any(l => l.DeformSprite != null) || !c.IsVisible) { continue; }
@@ -784,12 +784,12 @@ namespace Barotrauma
}; };
shuttleTickBox.TextBlock.RectTransform.SizeChanged += () => shuttleTickBox.TextBlock.RectTransform.SizeChanged += () =>
{ {
shuttleTickBox.TextBlock.AutoScale = true; shuttleTickBox.TextBlock.AutoScaleHorizontal = true;
shuttleTickBox.TextBlock.TextScale = 1.0f; shuttleTickBox.TextBlock.TextScale = 1.0f;
if (shuttleTickBox.TextBlock.TextScale < 0.75f) if (shuttleTickBox.TextBlock.TextScale < 0.75f)
{ {
shuttleTickBox.TextBlock.Wrap = true; shuttleTickBox.TextBlock.Wrap = true;
shuttleTickBox.TextBlock.AutoScale = true; shuttleTickBox.TextBlock.AutoScaleHorizontal = true;
shuttleTickBox.TextBlock.TextScale = 1.0f; shuttleTickBox.TextBlock.TextScale = 1.0f;
} }
}; };
@@ -831,13 +831,13 @@ namespace Barotrauma
if (child is GUITextBlock textBlock) if (child is GUITextBlock textBlock)
{ {
textBlock.TextScale = 1; textBlock.TextScale = 1;
textBlock.AutoScale = true; textBlock.AutoScaleHorizontal = true;
textBlock.SetTextPos(); textBlock.SetTextPos();
} }
else if (child is GUITickBox tickBox) else if (child is GUITickBox tickBox)
{ {
tickBox.TextBlock.TextScale = 1; tickBox.TextBlock.TextScale = 1;
tickBox.TextBlock.AutoScale = true; tickBox.TextBlock.AutoScaleHorizontal = true;
tickBox.TextBlock.SetTextPos(); tickBox.TextBlock.SetTextPos();
} }
} }
@@ -1827,7 +1827,7 @@ namespace Barotrauma
{ {
UserData = selectedClient UserData = selectedClient
}; };
viewSteamProfileButton.TextBlock.AutoScale = true; viewSteamProfileButton.TextBlock.AutoScaleHorizontal = true;
viewSteamProfileButton.OnClicked = (bt, userdata) => viewSteamProfileButton.OnClicked = (bt, userdata) =>
{ {
Steamworks.SteamFriends.OpenWebOverlay("https://steamcommunity.com/profiles/" + selectedClient.SteamID.ToString()); Steamworks.SteamFriends.OpenWebOverlay("https://steamcommunity.com/profiles/" + selectedClient.SteamID.ToString());
@@ -2694,7 +2694,7 @@ namespace Barotrauma
SelectedColor = Color.Transparent, SelectedColor = Color.Transparent,
TextColor = jobPrefab.UIColor, TextColor = jobPrefab.UIColor,
CanBeFocused = false, CanBeFocused = false,
AutoScale = true AutoScaleHorizontal = true
}; };
textBlock.RectTransform.SizeChanged += () => { textBlock.TextScale = 1.0f; }; textBlock.RectTransform.SizeChanged += () => { textBlock.TextScale = 1.0f; };
@@ -185,7 +185,7 @@ namespace Barotrauma
{ {
Padding = Vector4.Zero, Padding = Vector4.Zero,
ForceUpperCase = true, ForceUpperCase = true,
AutoScale = true AutoScaleHorizontal = true
}; };
var infoHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.33f), topRow.RectTransform), isHorizontal: true, Anchor.BottomLeft) { RelativeSpacing = 0.01f, Stretch = false }; var infoHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.33f), topRow.RectTransform), isHorizontal: true, Anchor.BottomLeft) { RelativeSpacing = 0.01f, Stretch = false };
@@ -279,7 +279,7 @@ namespace Barotrauma
var filterTitle = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), filtersHolder.RectTransform), TextManager.Get("FilterServers"), font: GUI.SubHeadingFont) var filterTitle = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), filtersHolder.RectTransform), TextManager.Get("FilterServers"), font: GUI.SubHeadingFont)
{ {
Padding = Vector4.Zero, Padding = Vector4.Zero,
AutoScale = true, AutoScaleHorizontal = true,
CanBeFocused = false CanBeFocused = false
}; };
@@ -1608,7 +1608,6 @@ namespace Barotrauma
if (serverInfo.OwnerVerified) if (serverInfo.OwnerVerified)
{ {
DebugConsole.NewMessage(serverInfo.OwnerID + " verified!");
var childrenToRemove = serverList.Content.FindChildren(c => (c.UserData is ServerInfo info) && info != serverInfo && var childrenToRemove = serverList.Content.FindChildren(c => (c.UserData is ServerInfo info) && info != serverInfo &&
(serverInfo.OwnerID != 0 ? info.OwnerID == serverInfo.OwnerID : info.IP == serverInfo.IP)).ToList(); (serverInfo.OwnerID != 0 ? info.OwnerID == serverInfo.OwnerID : info.IP == serverInfo.IP)).ToList();
foreach (var child in childrenToRemove) foreach (var child in childrenToRemove)
@@ -1637,7 +1636,7 @@ namespace Barotrauma
var compatibleBox = new GUITickBox(new RectTransform(new Vector2(columnRelativeWidth[0], 0.9f), serverContent.RectTransform, Anchor.Center), label: "") var compatibleBox = new GUITickBox(new RectTransform(new Vector2(columnRelativeWidth[0], 0.9f), serverContent.RectTransform, Anchor.Center), label: "")
{ {
Enabled = false, CanBeFocused = false,
Selected = Selected =
serverInfo.GameVersion == GameMain.Version.ToString() && serverInfo.GameVersion == GameMain.Version.ToString() &&
serverInfo.ContentPackagesMatch(GameMain.SelectedPackages), serverInfo.ContentPackagesMatch(GameMain.SelectedPackages),
@@ -1648,7 +1647,7 @@ namespace Barotrauma
{ {
ToolTip = TextManager.Get((serverInfo.HasPassword) ? "ServerListHasPassword" : "FilterPassword"), ToolTip = TextManager.Get((serverInfo.HasPassword) ? "ServerListHasPassword" : "FilterPassword"),
Selected = serverInfo.HasPassword, Selected = serverInfo.HasPassword,
Enabled = false, CanBeFocused = false,
UserData = "password" UserData = "password"
}; };
@@ -1659,12 +1658,17 @@ namespace Barotrauma
((serverInfo.OwnerID != 0 || serverInfo.LobbyID != 0) ? "[STEAMP2P] " : "[LIDGREN] ") + serverInfo.ServerName, ((serverInfo.OwnerID != 0 || serverInfo.LobbyID != 0) ? "[STEAMP2P] " : "[LIDGREN] ") + serverInfo.ServerName,
#endif #endif
style: "GUIServerListTextBox"); style: "GUIServerListTextBox");
serverName.UserData = serverName.Text;
serverName.RectTransform.SizeChanged += () =>
{
serverName.Text = ToolBox.LimitString(serverName.Text, serverName.Font, serverName.Rect.Width);
};
new GUITickBox(new RectTransform(new Vector2(columnRelativeWidth[3], 0.9f), serverContent.RectTransform, Anchor.Center), label: "") new GUITickBox(new RectTransform(new Vector2(columnRelativeWidth[3], 0.9f), serverContent.RectTransform, Anchor.Center), label: "")
{ {
ToolTip = TextManager.Get((serverInfo.GameStarted) ? "ServerListRoundStarted" : "ServerListRoundNotStarted"), ToolTip = TextManager.Get((serverInfo.GameStarted) ? "ServerListRoundStarted" : "ServerListRoundNotStarted"),
Selected = serverInfo.GameStarted, Selected = serverInfo.GameStarted,
Enabled = false CanBeFocused = false
}; };
var serverPlayers = new GUITextBlock(new RectTransform(new Vector2(columnRelativeWidth[4], 1.0f), serverContent.RectTransform), var serverPlayers = new GUITextBlock(new RectTransform(new Vector2(columnRelativeWidth[4], 1.0f), serverContent.RectTransform),
@@ -162,7 +162,7 @@ namespace Barotrauma
return true; return true;
} }
}; };
resetBtn.TextBlock.AutoScale = true; resetBtn.TextBlock.AutoScaleHorizontal = true;
new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), topPanelContents.RectTransform, Anchor.BottomCenter, Pivot.CenterRight) { RelativeOffset = new Vector2(0, 0.3f) }, TextManager.Get("spriteeditor.showgrid")) new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), topPanelContents.RectTransform, Anchor.BottomCenter, Pivot.CenterRight) { RelativeOffset = new Vector2(0, 0.3f) }, TextManager.Get("spriteeditor.showgrid"))
{ {
@@ -868,7 +868,7 @@ namespace Barotrauma
t.RectTransform.SizeChanged += () => t.RectTransform.SizeChanged += () =>
{ {
t.TextScale = 1.0f; t.TextScale = 1.0f;
t.AutoScale = true; t.AutoScaleHorizontal = true;
}; };
} }
@@ -1096,25 +1096,20 @@ namespace Barotrauma
{ {
var tagBtn = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tagHolder.Content.RectTransform, anchor: Anchor.CenterLeft), var tagBtn = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tagHolder.Content.RectTransform, anchor: Anchor.CenterLeft),
tag.CapitaliseFirstInvariant(), style: "GUIButtonRound"); tag.CapitaliseFirstInvariant(), style: "GUIButtonRound");
tagBtn.TextBlock.AutoScale = true; tagBtn.TextBlock.AutoScaleHorizontal = true;
tagBtn.Selected = itemEditor?.Tags?.Any(t => t.ToLowerInvariant() == tag) ?? false; tagBtn.Selected = itemEditor?.Tags?.Any(t => t.ToLowerInvariant() == tag) ?? false;
Color defaultTextColor = tagBtn.TextColor;
tagBtn.TextColor = tagBtn.Selected ? GUI.Style.Green : defaultTextColor;
tagBtn.OnClicked = (btn, userdata) => tagBtn.OnClicked = (btn, userdata) =>
{ {
if (!tagBtn.Selected) if (!tagBtn.Selected)
{ {
if (!(itemEditor?.Tags?.Any(t => t.ToLowerInvariant() == tag) ?? false)) { itemEditor = itemEditor?.WithTag(tagBtn.Text); } if (!(itemEditor?.Tags?.Any(t => t.ToLowerInvariant() == tag) ?? false)) { itemEditor = itemEditor?.WithTag(tagBtn.Text); }
tagBtn.Selected = true; tagBtn.Selected = true;
tagBtn.TextColor = GUI.Style.Green;
} }
else else
{ {
itemEditor?.Tags?.RemoveAll(t => t.ToLowerInvariant() == tagBtn.Text.ToLowerInvariant()); itemEditor?.Tags?.RemoveAll(t => t.ToLowerInvariant() == tagBtn.Text.ToLowerInvariant());
tagBtn.Selected = false; tagBtn.Selected = false;
tagBtn.TextColor = defaultTextColor;
} }
return true; return true;
}; };
@@ -1387,7 +1382,7 @@ namespace Barotrauma
return true; return true;
} }
}; };
publishBtn.TextBlock.AutoScale = true; publishBtn.TextBlock.AutoScaleHorizontal = true;
} }
private void OnPreviewImageSelected(GUIImage previewImageElement, string filePath) private void OnPreviewImageSelected(GUIImage previewImageElement, string filePath)
@@ -38,6 +38,8 @@ namespace Barotrauma
private GUIComponent showEntitiesPanel, entityCountPanel; private GUIComponent showEntitiesPanel, entityCountPanel;
private List<GUITickBox> showEntitiesTickBoxes = new List<GUITickBox>(); private List<GUITickBox> showEntitiesTickBoxes = new List<GUITickBox>();
private GUITextBlock subNameLabel;
private bool entityMenuOpen = true; private bool entityMenuOpen = true;
private float entityMenuOpenState = 1.0f; private float entityMenuOpenState = 1.0f;
public GUIComponent EntityMenu; public GUIComponent EntityMenu;
@@ -45,11 +47,16 @@ namespace Barotrauma
private GUIListBox entityList; private GUIListBox entityList;
private GUIButton toggleEntityMenuButton; private GUIButton toggleEntityMenuButton;
private GUITickBox defaultModeTickBox, wiringModeTickBox, characterModeTickBox;
private GUIComponent loadFrame, saveFrame; private GUIComponent loadFrame, saveFrame;
private GUITextBox nameBox, descriptionBox; private GUITextBox nameBox, descriptionBox;
private GUIButton selectedCategoryButton;
private GUITextBlock selectedCategoryText;
private readonly List<GUIButton> entityCategoryButtons = new List<GUIButton>(); private readonly List<GUIButton> entityCategoryButtons = new List<GUIButton>();
private MapEntityCategory? selectedCategory;
private GUIFrame hullVolumeFrame; private GUIFrame hullVolumeFrame;
@@ -61,8 +68,6 @@ namespace Barotrauma
private GUIDropDown linkedSubBox; private GUIDropDown linkedSubBox;
private GUIRadioButtonGroup modeButtonGroup;
//a Character used for picking up and manipulating items //a Character used for picking up and manipulating items
private Character dummyCharacter; private Character dummyCharacter;
@@ -89,15 +94,10 @@ namespace Barotrauma
get { return cam; } get { return cam; }
} }
public string GetSubName()
{
return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Name;
}
public string GetSubDescription() public string GetSubDescription()
{ {
string localizedDescription = TextManager.Get("submarine.description." + GetSubName(), true); string localizedDescription = TextManager.Get("submarine.description." + (Submarine.MainSub?.Name ?? ""), true);
if (localizedDescription != null) return localizedDescription; if (localizedDescription != null) { return localizedDescription; }
return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Description; return (Submarine.MainSub == null) ? "" : Submarine.MainSub.Description;
} }
@@ -214,11 +214,8 @@ namespace Barotrauma
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine"); new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
var nameLabel = new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft), subNameLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft),
"", font: GUI.LargeFont, textAlignment: Alignment.CenterLeft) TextManager.Get("unspecifiedsubfilename"), font: GUI.LargeFont, textAlignment: Alignment.CenterLeft);
{
TextGetter = GetSubName
};
linkedSubBox = new GUIDropDown(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform), linkedSubBox = new GUIDropDown(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform),
TextManager.Get("AddSubButton"), elementCount: 20) TextManager.Get("AddSubButton"), elementCount: 20)
@@ -238,52 +235,36 @@ namespace Barotrauma
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine"); new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
modeButtonGroup = new GUIRadioButtonGroup(); defaultModeTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "EditSubButton")
var defaultModeTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "EditSubButton")
{ {
ToolTip = TextManager.Get("SubEditorEditingMode"), ToolTip = TextManager.Get("SubEditorEditingMode"),
OnSelected = (GUITickBox tBox) => OnSelected = (GUITickBox tBox) =>
{ {
if (tBox.Selected) if (tBox.Selected) { SetMode(Mode.Default); }
{
SetMode(Mode.Default);
}
return true; return true;
} }
}; };
var characterModeTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "CharacterModeButton") characterModeTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "CharacterModeButton")
{ {
ToolTip = TextManager.Get("CharacterModeButton") + '\n' + TextManager.Get("CharacterModeToolTip"), ToolTip = TextManager.Get("CharacterModeButton") + '\n' + TextManager.Get("CharacterModeToolTip"),
OnSelected = (GUITickBox tBox) => OnSelected = (GUITickBox tBox) =>
{ {
if (tBox.Selected) SetMode(tBox.Selected ? Mode.Character : Mode.Default);
{
SetMode(Mode.Character);
}
return true; return true;
} }
}; };
var wiringModeTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "WiringModeButton") wiringModeTickBox = new GUITickBox(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "WiringModeButton")
{ {
ToolTip = TextManager.Get("WiringModeButton") + '\n' + TextManager.Get("WiringModeToolTip"), ToolTip = TextManager.Get("WiringModeButton") + '\n' + TextManager.Get("WiringModeToolTip"),
OnSelected = (GUITickBox tBox) => OnSelected = (GUITickBox tBox) =>
{ {
if (tBox.Selected) SetMode(tBox.Selected ? Mode.Wiring : Mode.Default);
{
SetMode(Mode.Wiring);
}
return true; return true;
} }
}; };
modeButtonGroup.AddRadioButton((int)Mode.Default, defaultModeTickBox);
modeButtonGroup.AddRadioButton((int)Mode.Character, characterModeTickBox);
modeButtonGroup.AddRadioButton((int)Mode.Wiring, wiringModeTickBox);
modeButtonGroup.Selected = (int)Mode.Default;
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine"); new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
new GUIButton(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "GenerateWaypointsButton") new GUIButton(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "GenerateWaypointsButton")
@@ -294,7 +275,7 @@ namespace Barotrauma
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine"); new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
var visibilityButton = new GUIButton(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "SetupVisibilityButton") var visibilityButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "SetupVisibilityButton")
{ {
ToolTip = TextManager.Get("SubEditorVisibilityButton") + '\n' + TextManager.Get("SubEditorVisibilityToolTip"), ToolTip = TextManager.Get("SubEditorVisibilityButton") + '\n' + TextManager.Get("SubEditorVisibilityToolTip"),
OnClicked = (btn, userData) => OnClicked = (btn, userData) =>
@@ -306,7 +287,7 @@ namespace Barotrauma
} }
}; };
var previouslyUsedButton = new GUIButton(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "RecentlyUsedButton") var previouslyUsedButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "RecentlyUsedButton")
{ {
ToolTip = TextManager.Get("PreviouslyUsedLabel"), ToolTip = TextManager.Get("PreviouslyUsedLabel"),
OnClicked = (btn, userData) => OnClicked = (btn, userData) =>
@@ -536,7 +517,7 @@ namespace Barotrauma
Visible = false Visible = false
}; };
var saveAssemblyButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.8f), saveAssemblyFrame.RectTransform, Anchor.Center), TextManager.Get("SaveItemAssembly")); var saveAssemblyButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.8f), saveAssemblyFrame.RectTransform, Anchor.Center), TextManager.Get("SaveItemAssembly"));
saveAssemblyButton.TextBlock.AutoScale = true; saveAssemblyButton.TextBlock.AutoScaleHorizontal = true;
saveAssemblyButton.OnClicked += (btn, userdata) => saveAssemblyButton.OnClicked += (btn, userdata) =>
{ {
CreateSaveAssemblyScreen(); CreateSaveAssemblyScreen();
@@ -567,7 +548,7 @@ namespace Barotrauma
var paddedTab = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.96f), EntityMenu.RectTransform, Anchor.BottomCenter), childAnchor: Anchor.TopCenter) var paddedTab = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.96f), EntityMenu.RectTransform, Anchor.BottomCenter), childAnchor: Anchor.TopCenter)
{ {
RelativeSpacing = 0.05f, RelativeSpacing = 0.04f,
Stretch = true Stretch = true
}; };
@@ -576,11 +557,19 @@ namespace Barotrauma
Stretch = true Stretch = true
}; };
var selectedCategoryButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), entityMenuTop.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "CategoryButton.All") selectedCategoryButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), entityMenuTop.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "CategoryButton.All")
{ {
CanBeFocused = false CanBeFocused = false
}; };
var selectedCategoryText = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1.0f), entityMenuTop.RectTransform), TextManager.Get("MapEntityCategory.All"), font: GUI.LargeFont); selectedCategoryText = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1.0f), entityMenuTop.RectTransform), TextManager.Get("MapEntityCategory.All"), font: GUI.LargeFont);
var filterText = new GUITextBlock(new RectTransform(new Vector2(0.1f, 1.0f), entityMenuTop.RectTransform), TextManager.Get("serverlog.filter"), font: GUI.SubHeadingFont);
filterText.RectTransform.MaxSize = new Point((int)(filterText.TextSize.X * 1.5f), int.MaxValue);
entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.17f, 1.0f), entityMenuTop.RectTransform), font: GUI.Font, createClearButton: true);
entityFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; };
//spacing
new GUIFrame(new RectTransform(new Vector2(0.075f, 1.0f), entityMenuTop.RectTransform), style: null);
entityCategoryButtons.Clear(); entityCategoryButtons.Clear();
entityCategoryButtons.Add( entityCategoryButtons.Add(
@@ -588,10 +577,8 @@ namespace Barotrauma
{ {
OnClicked = (btn, userdata) => OnClicked = (btn, userdata) =>
{ {
entityCategoryButtons.ForEach(b => b.Selected = b == btn); if (!string.IsNullOrEmpty(entityFilterBox.Text)) { ClearFilter(); }
selectedCategoryText.Text = TextManager.Get("MapEntityCategory.All"); OpenEntityMenu(null);
selectedCategoryButton.ApplyStyle(GUI.Style.GetComponentStyle("CategoryButton.All"));
ClearFilter();
return true; return true;
} }
}); });
@@ -605,20 +592,14 @@ namespace Barotrauma
ToolTip = TextManager.Get("MapEntityCategory." + category.ToString()), ToolTip = TextManager.Get("MapEntityCategory." + category.ToString()),
OnClicked = (btn, userdata) => OnClicked = (btn, userdata) =>
{ {
entityMenuOpen = true; if (!string.IsNullOrEmpty(entityFilterBox.Text)) { ClearFilter(); }
MapEntityCategory newCategory = (MapEntityCategory)userdata; MapEntityCategory newCategory = (MapEntityCategory)userdata;
selectedCategoryText.Text = TextManager.Get("MapEntityCategory." + newCategory.ToString());
selectedCategoryButton.ApplyStyle(GUI.Style.GetComponentStyle("CategoryButton." + category.ToString()));
OpenEntityMenu(newCategory); OpenEntityMenu(newCategory);
return true; return true;
} }
}); });
} }
entityCategoryButtons.ForEach(b => b.RectTransform.MaxSize = new Point(b.Rect.Height));
var filterText = new GUITextBlock(new RectTransform(new Vector2(0.1f, 1.0f), entityMenuTop.RectTransform), TextManager.Get("serverlog.filter"), font: GUI.SubHeadingFont);
filterText.RectTransform.MaxSize = new Point((int)(filterText.TextSize.X * 1.5f), int.MaxValue);
entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.2f, 1.0f), entityMenuTop.RectTransform), font: GUI.Font, createClearButton: true);
entityFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; };
new GUIFrame(new RectTransform(new Vector2(0.8f, 0.01f), paddedTab.RectTransform), style: "HorizontalLine"); new GUIFrame(new RectTransform(new Vector2(0.8f, 0.01f), paddedTab.RectTransform), style: "HorizontalLine");
@@ -636,7 +617,7 @@ namespace Barotrauma
{ {
entityList.Content.ClearChildren(); entityList.Content.ClearChildren();
int entitiesPerRow = (int)Math.Ceiling(entityList.Content.Rect.Width / Math.Max(125 * GUI.Scale, 100)); int entitiesPerRow = (int)Math.Ceiling(entityList.Content.Rect.Width / Math.Max(125 * GUI.Scale, 60));
foreach (MapEntityPrefab ep in MapEntityPrefab.List) foreach (MapEntityPrefab ep in MapEntityPrefab.List)
{ {
@@ -762,6 +743,9 @@ namespace Barotrauma
UpdateEntityList(); UpdateEntityList();
string name = (Submarine.MainSub == null) ? TextManager.Get("unspecifiedsubfilename") : Submarine.MainSub.Name;
subNameLabel.Text = ToolBox.LimitString(name, subNameLabel.Font, subNameLabel.Rect.Width);
foreach (MapEntityPrefab prefab in MapEntityPrefab.List) foreach (MapEntityPrefab prefab in MapEntityPrefab.List)
{ {
prefab.sprite?.EnsureLazyLoaded(); prefab.sprite?.EnsureLazyLoaded();
@@ -1000,7 +984,6 @@ namespace Barotrauma
if (string.IsNullOrWhiteSpace(nameBox.Text)) if (string.IsNullOrWhiteSpace(nameBox.Text))
{ {
GUI.AddMessage(TextManager.Get("SubNameMissingWarning"), GUI.Style.Red); GUI.AddMessage(TextManager.Get("SubNameMissingWarning"), GUI.Style.Red);
nameBox.Flash(); nameBox.Flash();
return false; return false;
} }
@@ -1069,6 +1052,8 @@ namespace Barotrauma
linkedSubBox.AddItem(sub.Name, sub); linkedSubBox.AddItem(sub.Name, sub);
} }
subNameLabel.Text = ToolBox.LimitString(Submarine.MainSub.Name, subNameLabel.Font, subNameLabel.Rect.Width);
saveFrame = null; saveFrame = null;
return false; return false;
@@ -1102,8 +1087,7 @@ namespace Barotrauma
nameBox = new GUITextBox(new RectTransform(new Vector2(.95f, 0.05f), leftColumn.RectTransform)) nameBox = new GUITextBox(new RectTransform(new Vector2(.95f, 0.05f), leftColumn.RectTransform))
{ {
OnEnterPressed = ChangeSubName, OnEnterPressed = ChangeSubName
Text = GetSubName()
}; };
nameBox.OnTextChanged += (textBox, text) => nameBox.OnTextChanged += (textBox, text) =>
{ {
@@ -1627,6 +1611,9 @@ namespace Barotrauma
Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position); Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position);
Submarine.MainSub.UpdateTransform(); Submarine.MainSub.UpdateTransform();
string name = Submarine.MainSub.Name;
subNameLabel.Text = ToolBox.LimitString(name, subNameLabel.Font, subNameLabel.Rect.Width);
cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition; cam.Position = Submarine.MainSub.Position + Submarine.MainSub.HiddenSubPosition;
loadFrame = null; loadFrame = null;
@@ -1700,22 +1687,25 @@ namespace Barotrauma
msgBox.Buttons[1].OnClicked += msgBox.Close; msgBox.Buttons[1].OnClicked += msgBox.Close;
} }
private bool OpenEntityMenu(MapEntityCategory selectedCategory) private bool OpenEntityMenu(MapEntityCategory? selectedCategory)
{ {
entityFilterBox.Text = ""; foreach (GUIButton categoryButton in entityCategoryButtons)
{
categoryButton.Selected = selectedCategory.HasValue ?
categoryButton.UserData is MapEntityCategory category && selectedCategory.Value == category :
categoryButton.UserData == null;
string categoryName = selectedCategory.HasValue ? selectedCategory.Value.ToString() : "All";
selectedCategoryText.Text = TextManager.Get("MapEntityCategory." + categoryName);
selectedCategoryButton.ApplyStyle(GUI.Style.GetComponentStyle("CategoryButton." + categoryName));
}
this.selectedCategory = selectedCategory;
SetMode(Mode.Default); SetMode(Mode.Default);
saveFrame = null; saveFrame = null;
loadFrame = null; loadFrame = null;
ClearFilter();
foreach (GUIButton button in entityCategoryButtons)
{
button.Selected =
button.UserData != null &&
(MapEntityCategory)button.UserData == selectedCategory;
}
foreach (GUIComponent child in toggleEntityMenuButton.Children) foreach (GUIComponent child in toggleEntityMenuButton.Children)
{ {
child.SpriteEffects = entityMenuOpen ? SpriteEffects.None : SpriteEffects.FlipVertically; child.SpriteEffects = entityMenuOpen ? SpriteEffects.None : SpriteEffects.FlipVertically;
@@ -1723,7 +1713,7 @@ namespace Barotrauma
foreach (GUIComponent child in entityList.Content.Children) foreach (GUIComponent child in entityList.Content.Children)
{ {
child.Visible = ((MapEntityPrefab)child.UserData).Category == selectedCategory; child.Visible = !selectedCategory.HasValue || ((MapEntityPrefab)child.UserData).Category == selectedCategory;
} }
entityList.UpdateScrollBarSize(); entityList.UpdateScrollBarSize();
entityList.BarScroll = 0.0f; entityList.BarScroll = 0.0f;
@@ -1733,14 +1723,9 @@ namespace Barotrauma
private bool FilterEntities(string filter) private bool FilterEntities(string filter)
{ {
foreach (GUIButton button in entityCategoryButtons)
{
button.Selected = false;
}
if (string.IsNullOrWhiteSpace(filter)) if (string.IsNullOrWhiteSpace(filter))
{ {
entityList.Content.Children.ForEach(c => c.Visible = true); entityList.Content.Children.ForEach(c => c.Visible = !selectedCategory.HasValue || selectedCategory == ((MapEntityPrefab)c.UserData).Category);
return true; return true;
} }
@@ -1748,7 +1733,9 @@ namespace Barotrauma
foreach (GUIComponent child in entityList.Content.Children) foreach (GUIComponent child in entityList.Content.Children)
{ {
var textBlock = child.GetChild<GUITextBlock>(); var textBlock = child.GetChild<GUITextBlock>();
child.Visible = ((MapEntityPrefab)child.UserData).Name.ToLower().Contains(filter); child.Visible =
(!selectedCategory.HasValue || selectedCategory == ((MapEntityPrefab)child.UserData).Category) &&
((MapEntityPrefab)child.UserData).Name.ToLower().Contains(filter);
} }
entityList.UpdateScrollBarSize(); entityList.UpdateScrollBarSize();
entityList.BarScroll = 0.0f; entityList.BarScroll = 0.0f;
@@ -1768,9 +1755,13 @@ namespace Barotrauma
public void SetMode(Mode mode) public void SetMode(Mode mode)
{ {
if (mode == this.mode) { return; } if (mode == this.mode) { return; }
this.mode = mode; this.mode = mode;
modeButtonGroup.Selected = (int)mode;
defaultModeTickBox.Selected = mode == Mode.Default;
defaultModeTickBox.CanBeFocused = !defaultModeTickBox.Selected;
characterModeTickBox.Selected = mode == Mode.Character;
wiringModeTickBox.Selected = mode == Mode.Wiring;
switch (mode) switch (mode)
{ {
@@ -1856,9 +1847,10 @@ namespace Barotrauma
if (!child.Enabled) { child.TextColor *= 0.5f; } if (!child.Enabled) { child.TextColor *= 0.5f; }
} }
contextMenu.Content.Children.ForEach(c => c.RectTransform.MinSize = new Point(0, c.Rect.Height));
contextMenu.RectTransform.NonScaledSize = new Point( contextMenu.RectTransform.NonScaledSize = new Point(
contextMenu.Rect.Width, contextMenu.Rect.Width,
(int)((contextMenu.Content.CountChildren * 18) * GUI.Scale)); (int)((contextMenu.Content.CountChildren * 20) * GUI.Scale));
contextMenu.OnSelected = (GUIComponent component, object obj) => contextMenu.OnSelected = (GUIComponent component, object obj) =>
{ {
@@ -2412,6 +2404,11 @@ namespace Barotrauma
hullVolumeFrame.Visible = MapEntity.SelectedList.Any(s => s is Hull); hullVolumeFrame.Visible = MapEntity.SelectedList.Any(s => s is Hull);
saveAssemblyFrame.Visible = MapEntity.SelectedList.Count > 0; saveAssemblyFrame.Visible = MapEntity.SelectedList.Count > 0;
if (PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Tab))
{
entityFilterBox.Select();
}
cam.MoveCamera((float)deltaTime, true); cam.MoveCamera((float)deltaTime, true);
if (PlayerInput.MidButtonHeld()) if (PlayerInput.MidButtonHeld())
{ {
@@ -2615,9 +2612,11 @@ namespace Barotrauma
GUI.DrawLine(spriteBatch, new Vector2(Submarine.MainSub.HiddenSubPosition.X, -cam.WorldView.Y), new Vector2(Submarine.MainSub.HiddenSubPosition.X, -(cam.WorldView.Y - cam.WorldView.Height)), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom)); GUI.DrawLine(spriteBatch, new Vector2(Submarine.MainSub.HiddenSubPosition.X, -cam.WorldView.Y), new Vector2(Submarine.MainSub.HiddenSubPosition.X, -(cam.WorldView.Y - cam.WorldView.Height)), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom));
GUI.DrawLine(spriteBatch, new Vector2(cam.WorldView.X, -Submarine.MainSub.HiddenSubPosition.Y), new Vector2(cam.WorldView.Right, -Submarine.MainSub.HiddenSubPosition.Y), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom)); GUI.DrawLine(spriteBatch, new Vector2(cam.WorldView.X, -Submarine.MainSub.HiddenSubPosition.Y), new Vector2(cam.WorldView.Right, -Submarine.MainSub.HiddenSubPosition.Y), Color.White * 0.5f, 1.0f, (int)(2.0f / cam.Zoom));
} }
Submarine.DrawBack(spriteBatch, true, e => e is Structure s && (e.SpriteDepth >= 0.9f || s.Prefab.BackgroundSprite != null));
spriteBatch.End();
Submarine.DrawBack(spriteBatch, editing: true); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
Submarine.DrawBack(spriteBatch, true, e => !(e is Structure) || e.SpriteDepth < 0.9f);
spriteBatch.End(); spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
@@ -277,7 +277,7 @@ namespace Barotrauma
layoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, RectTransform)) { AbsoluteSpacing = (int)(5 * GUI.Scale) }; layoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, RectTransform)) { AbsoluteSpacing = (int)(5 * GUI.Scale) };
if (showName) if (showName)
{ {
new GUITextBlock(new RectTransform(new Point(layoutGroup.Rect.Width, this.elementHeight), layoutGroup.RectTransform), entity.Name, font: titleFont ?? GUI.Font) new GUITextBlock(new RectTransform(new Point(layoutGroup.Rect.Width, this.elementHeight), layoutGroup.RectTransform, isFixedSize: true), entity.Name, font: titleFont ?? GUI.Font)
{ {
TextColor = Color.White, TextColor = Color.White,
Color = Color.Black Color = Color.Black
@@ -392,7 +392,7 @@ namespace Barotrauma
public GUIComponent CreateBoolField(ISerializableEntity entity, SerializableProperty property, bool value, string displayName, string toolTip) public GUIComponent CreateBoolField(ISerializableEntity entity, SerializableProperty property, bool value, string displayName, string toolTip)
{ {
GUITickBox propertyTickBox = new GUITickBox(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform), displayName) GUITickBox propertyTickBox = new GUITickBox(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), displayName)
{ {
Font = GUI.SmallFont, Font = GUI.SmallFont,
Selected = value, Selected = value,
@@ -412,7 +412,7 @@ namespace Barotrauma
public GUIComponent CreateIntField(ISerializableEntity entity, SerializableProperty property, int value, string displayName, string toolTip) public GUIComponent CreateIntField(ISerializableEntity entity, SerializableProperty property, int value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -453,7 +453,7 @@ namespace Barotrauma
public GUIComponent CreateFloatField(ISerializableEntity entity, SerializableProperty property, float value, string displayName, string toolTip) public GUIComponent CreateFloatField(ISerializableEntity entity, SerializableProperty property, float value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - 1, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - 1, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -476,6 +476,7 @@ namespace Barotrauma
{ {
if (property.TrySetValue(entity, numInput.FloatValue)) if (property.TrySetValue(entity, numInput.FloatValue))
{ {
numInput.FloatValue = (float)property.GetValue(entity);
TrySendNetworkUpdate(entity, property); TrySendNetworkUpdate(entity, property);
} }
}; };
@@ -485,7 +486,7 @@ namespace Barotrauma
public GUIComponent CreateEnumField(ISerializableEntity entity, SerializableProperty property, object value, string displayName, string toolTip) public GUIComponent CreateEnumField(ISerializableEntity entity, SerializableProperty property, object value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -514,7 +515,7 @@ namespace Barotrauma
public GUIComponent CreateEnumFlagField(ISerializableEntity entity, SerializableProperty property, object value, string displayName, string toolTip) public GUIComponent CreateEnumFlagField(ISerializableEntity entity, SerializableProperty property, object value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -547,7 +548,7 @@ namespace Barotrauma
public GUIComponent CreateStringField(ISerializableEntity entity, SerializableProperty property, string value, string displayName, string toolTip) public GUIComponent CreateStringField(ISerializableEntity entity, SerializableProperty property, string value, string displayName, string toolTip)
{ {
var frame = new GUILayoutGroup(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) var frame = new GUILayoutGroup(new RectTransform(new Point(Rect.Width, elementHeight), layoutGroup.RectTransform, isFixedSize: true), isHorizontal: true, childAnchor: Anchor.CenterLeft)
{ {
Stretch = true Stretch = true
}; };
@@ -608,7 +609,7 @@ namespace Barotrauma
public GUIComponent CreatePointField(ISerializableEntity entity, SerializableProperty property, Point value, string displayName, string toolTip) public GUIComponent CreatePointField(ISerializableEntity entity, SerializableProperty property, Point value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -661,7 +662,7 @@ namespace Barotrauma
public GUIComponent CreateVector2Field(ISerializableEntity entity, SerializableProperty property, Vector2 value, string displayName, string toolTip) public GUIComponent CreateVector2Field(ISerializableEntity entity, SerializableProperty property, Vector2 value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - inputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -716,7 +717,7 @@ namespace Barotrauma
public GUIComponent CreateVector3Field(ISerializableEntity entity, SerializableProperty property, Vector3 value, string displayName, string toolTip) public GUIComponent CreateVector3Field(ISerializableEntity entity, SerializableProperty property, Vector3 value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - largeInputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - largeInputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -775,7 +776,7 @@ namespace Barotrauma
public GUIComponent CreateVector4Field(ISerializableEntity entity, SerializableProperty property, Vector4 value, string displayName, string toolTip) public GUIComponent CreateVector4Field(ISerializableEntity entity, SerializableProperty property, Vector4 value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - largeInputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - largeInputFieldWidth, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = toolTip ToolTip = toolTip
@@ -838,7 +839,7 @@ namespace Barotrauma
public GUIComponent CreateColorField(ISerializableEntity entity, SerializableProperty property, Color value, string displayName, string toolTip) public GUIComponent CreateColorField(ISerializableEntity entity, SerializableProperty property, Color value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - largeInputFieldWidth, 1), frame.RectTransform) { MinSize = new Point(80, 26) }, displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(1.0f - largeInputFieldWidth, 1), frame.RectTransform) { MinSize = new Point(80, 26) }, displayName, font: GUI.SmallFont)
{ {
ToolTip = displayName + '\n' + toolTip ToolTip = displayName + '\n' + toolTip
@@ -910,7 +911,7 @@ namespace Barotrauma
public GUIComponent CreateRectangleField(ISerializableEntity entity, SerializableProperty property, Rectangle value, string displayName, string toolTip) public GUIComponent CreateRectangleField(ISerializableEntity entity, SerializableProperty property, Rectangle value, string displayName, string toolTip)
{ {
var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform), color: Color.Transparent); var frame = new GUIFrame(new RectTransform(new Point(Rect.Width, Math.Max(elementHeight, 26)), layoutGroup.RectTransform, isFixedSize: true), color: Color.Transparent);
var label = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1), frame.RectTransform), displayName, font: GUI.SmallFont) var label = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1), frame.RectTransform), displayName, font: GUI.SmallFont)
{ {
ToolTip = displayName + '\n' + toolTip ToolTip = displayName + '\n' + toolTip
@@ -120,6 +120,27 @@ namespace OpenAL
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetError")] [DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetError")]
public static extern int GetError(IntPtr device); public static extern int GetError(IntPtr device);
public static string GetErrorString(int errorCode)
{
switch (errorCode)
{
case NoError:
return "No error";
case InvalidContext:
return "Invalid context";
case InvalidDevice:
return "Invalid device";
case InvalidEnum:
return "Invalid enum";
case InvalidValue:
return "Invalid value";
case OutOfMemory:
return "Out of memory";
default:
return "Unknown error";
}
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcIsExtensionPresent")] [DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcIsExtensionPresent")]
public static extern bool IsExtensionPresent(IntPtr device, string extname); public static extern bool IsExtensionPresent(IntPtr device, string extname);
@@ -196,30 +196,38 @@ namespace Barotrauma.Sounds
streamingThread = null; streamingThread = null;
categoryModifiers = null; categoryModifiers = null;
alcDevice = Alc.OpenDevice(null); int alcError = Alc.NoError;
if (alcDevice == null)
string deviceName = Alc.GetString(IntPtr.Zero, Alc.DefaultDeviceSpecifier);
DebugConsole.NewMessage($"Attempting to open ALC device \"{deviceName}\"");
alcDevice = IntPtr.Zero;
for (int i = 0; i < 3; i++)
{ {
DebugConsole.ThrowError("Failed to open an ALC device! Disabling audio playback..."); alcDevice = Alc.OpenDevice(deviceName);
Disabled = true; if (alcDevice == IntPtr.Zero)
return;
}
int alcError = Alc.GetError(alcDevice);
if (alcError != Alc.NoError)
{
//The audio device probably wasn't ready, this happens quite often
//Just wait a while and try again
Thread.Sleep(100);
alcDevice = Alc.OpenDevice(null);
alcError = Alc.GetError(alcDevice);
if (alcError != Alc.NoError)
{ {
DebugConsole.ThrowError("Error initializing ALC device: " + alcError.ToString() + ". Disabling audio playback..."); DebugConsole.NewMessage($"ALC device initialization attempt #{i + 1} failed: device is null");
Disabled = true;
return;
} }
else
{
alcError = Alc.GetError(alcDevice);
if (alcError != Alc.NoError)
{
DebugConsole.NewMessage($"ALC device initialization attempt #{i + 1} failed: error code {Alc.GetErrorString(alcError)}");
bool closed = Alc.CloseDevice(alcDevice);
if (!closed)
{
DebugConsole.NewMessage($"Failed to close ALC device");
}
alcDevice = IntPtr.Zero;
}
}
}
if (alcDevice == IntPtr.Zero)
{
DebugConsole.ThrowError("ALC device creation failed too many times!");
Disabled = true;
} }
int[] alcContextAttrs = new int[] { }; int[] alcContextAttrs = new int[] { };
@@ -241,7 +249,7 @@ namespace Barotrauma.Sounds
alcError = Alc.GetError(alcDevice); alcError = Alc.GetError(alcDevice);
if (alcError != Alc.NoError) if (alcError != Alc.NoError)
{ {
DebugConsole.ThrowError("Error after assigning ALC context: " + alcError.ToString() + ". Disabling audio playback..."); DebugConsole.ThrowError("Error after assigning ALC context: " + Alc.GetErrorString(alcError) + ". Disabling audio playback...");
Disabled = true; Disabled = true;
return; return;
} }
@@ -18,9 +18,10 @@ namespace Barotrauma
private const string infoTextPath = "Content/Texts"; private const string infoTextPath = "Content/Texts";
private const string xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; private const string xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
private static string[,] translatedLanguageNames = new string[12, 2] { { "English", "English" }, { "French", "Français" }, { "German", "Deutsch" }, private static string[,] translatedLanguageNames = new string[13, 2] { { "English", "English" }, { "French", "Français" }, { "German", "Deutsch" },
{ "Russian", "Русский" }, { "Brazilian Portuguese", "Português brasileiro" }, { "Simplified Chinese", "中文(简体)" }, { "Traditional Chinese", "中文(繁體)" }, { "Russian", "Русский" }, { "Brazilian Portuguese", "Português brasileiro" }, { "Simplified Chinese", "中文(简体)" }, { "Traditional Chinese", "中文(繁體)" },
{ "Castilian Spanish", "Castellano" }, { "Latinamerican Spanish", "Español Latinoamericano" }, { "Polish", "Polski" }, { "Turkish", "Türkçe" }, { "Japanese", "日本語" } }; { "Castilian Spanish", "Castellano" }, { "Latinamerican Spanish", "Español Latinoamericano" }, { "Polish", "Polski" }, { "Turkish", "Türkçe" },
{ "Japanese", "日本語" }, { "Korean", "한국어" } };
public static void Convert() public static void Convert()
{ {
@@ -81,7 +82,7 @@ namespace Barotrauma
continue; continue;
} }
string xmlFileFullPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}/NpcConversations_{languageNoWhitespace}_NEW.xml"; string xmlFileFullPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}/NpcConversations_{languageNoWhitespace}_NEW.xml";
File.WriteAllLines(xmlFileFullPath, xmlContent); File.WriteAllLines(xmlFileFullPath, xmlContent, Encoding.UTF8);
DebugConsole.NewMessage("Conversation localization .xml file successfully created at: " + xmlFileFullPath); DebugConsole.NewMessage("Conversation localization .xml file successfully created at: " + xmlFileFullPath);
} }
@@ -94,7 +95,7 @@ namespace Barotrauma
continue; continue;
} }
string xmlFileFullPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}/{languageNoWhitespace}Vanilla_NEW.xml"; string xmlFileFullPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}/{languageNoWhitespace}Vanilla_NEW.xml";
File.WriteAllLines(xmlFileFullPath, xmlContent); File.WriteAllLines(xmlFileFullPath, xmlContent, Encoding.UTF8);
DebugConsole.NewMessage("InfoText localization .xml file successfully created at: " + xmlFileFullPath); DebugConsole.NewMessage("InfoText localization .xml file successfully created at: " + xmlFileFullPath);
} }
@@ -114,7 +114,7 @@ namespace Barotrauma
public static string WrapText(string text, float lineLength, ScalableFont font, float textScale = 1.0f, bool playerInput = false) //TODO: could integrate this into the ScalableFont class directly public static string WrapText(string text, float lineLength, ScalableFont font, float textScale = 1.0f, bool playerInput = false) //TODO: could integrate this into the ScalableFont class directly
{ {
Vector2 textSize = font.MeasureString(text); Vector2 textSize = font.MeasureString(text);
if (textSize.X < lineLength) { return text; } if (textSize.X <= lineLength) { return text; }
if (!playerInput) if (!playerInput)
{ {
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product> <Product>Barotrauma</Product>
<Version>0.9.702.0</Version> <Version>0.9.703.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName> <AssemblyName>Barotrauma</AssemblyName>
+1 -1
View File
@@ -11,7 +11,7 @@
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName> <AssemblyName>Barotrauma</AssemblyName>
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon> <ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
<ReleaseVersion>0.9.0.0</ReleaseVersion> <ReleaseVersion>0.9.703.0</ReleaseVersion>
<Configurations>Debug;Release;Unstable</Configurations> <Configurations>Debug;Release;Unstable</Configurations>
</PropertyGroup> </PropertyGroup>
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma</Product> <Product>Barotrauma</Product>
<Version>0.9.702.0</Version> <Version>0.9.703.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>Barotrauma</AssemblyName> <AssemblyName>Barotrauma</AssemblyName>
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product> <Product>Barotrauma Dedicated Server</Product>
<Version>0.9.702.0</Version> <Version>0.9.703.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName> <AssemblyName>DedicatedServer</AssemblyName>
+1 -1
View File
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product> <Product>Barotrauma Dedicated Server</Product>
<Version>0.9.702.0</Version> <Version>0.9.703.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName> <AssemblyName>DedicatedServer</AssemblyName>
@@ -248,6 +248,16 @@ namespace Barotrauma
} }
} }
private static Client FindClient(string arg)
{
int.TryParse(arg, out int id);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
client ??= GameMain.Server.ConnectedClients.Find(c => c.EndpointMatches(arg));
client ??= GameMain.Server.ConnectedClients.Find(c => c.SteamID == Steam.SteamManager.SteamIDStringToUInt64(arg));
client ??= GameMain.Server.ConnectedClients.Find(c => Homoglyphs.Compare(c.Name, arg));
return client;
}
private static void AssignOnClientRequestExecute(string names, Action<Client, Vector2, string[]> onClientRequestExecute) private static void AssignOnClientRequestExecute(string names, Action<Client, Vector2, string[]> onClientRequestExecute)
{ {
var matchingCommand = commands.Find(c => c.names.Intersect(names.Split('|')).Count() > 0); var matchingCommand = commands.Find(c => c.names.Intersect(names.Split('|')).Count() > 0);
@@ -406,11 +416,10 @@ namespace Barotrauma
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
ThrowError("Client id \"" + id + "\" not found."); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -430,7 +439,7 @@ namespace Barotrauma
client.GivePermission(permission); client.GivePermission(permission);
GameMain.Server.UpdateClientPermissions(client); GameMain.Server.UpdateClientPermissions(client);
NewMessage("Granted " + perm + " permissions to " + client.Name + ".", Color.White); NewMessage("Granted " + perm + " permissions to " + client.Name + ".", Color.White);
}); }, args, 2);
}); });
AssignOnExecute("revokeperm", (string[] args) => AssignOnExecute("revokeperm", (string[] args) =>
@@ -442,11 +451,10 @@ namespace Barotrauma
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
ThrowError("Client id \"" + id + "\" not found."); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -466,7 +474,7 @@ namespace Barotrauma
client.RemovePermission(permission); client.RemovePermission(permission);
GameMain.Server.UpdateClientPermissions(client); GameMain.Server.UpdateClientPermissions(client);
NewMessage("Revoked " + perm + " permissions from " + client.Name + ".", Color.White); NewMessage("Revoked " + perm + " permissions from " + client.Name + ".", Color.White);
}); }, args, 2);
}); });
AssignOnExecute("giverank", (string[] args) => AssignOnExecute("giverank", (string[] args) =>
@@ -474,15 +482,14 @@ namespace Barotrauma
if (GameMain.Server == null) return; if (GameMain.Server == null) return;
if (args.Length < 1) if (args.Length < 1)
{ {
NewMessage("giverank [id]: Assigns a specific rank(= a set of administrative permissions) to the player with the specified client ID.", Color.Cyan); NewMessage("giverank [id/steamid/endpoint/name] [rank]: Assigns a specific rank (= a set of administrative permissions) to the player with the specified client ID.", Color.Cyan);
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
ThrowError("Client id \"" + id + "\" not found."); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -504,7 +511,7 @@ namespace Barotrauma
client.SetPermissions(preset.Permissions, preset.PermittedCommands); client.SetPermissions(preset.Permissions, preset.PermittedCommands);
GameMain.Server.UpdateClientPermissions(client); GameMain.Server.UpdateClientPermissions(client);
NewMessage("Assigned the rank \"" + preset.Name + "\" to " + client.Name + ".", Color.White); NewMessage("Assigned the rank \"" + preset.Name + "\" to " + client.Name + ".", Color.White);
}); }, args, 2);
}); });
AssignOnExecute("givecommandperm", (string[] args) => AssignOnExecute("givecommandperm", (string[] args) =>
@@ -516,11 +523,10 @@ namespace Barotrauma
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
ThrowError("Client id \"" + id + "\" not found."); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -546,7 +552,7 @@ namespace Barotrauma
client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Union(grantedCommands).Distinct().ToList()); client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Union(grantedCommands).Distinct().ToList());
GameMain.Server.UpdateClientPermissions(client); GameMain.Server.UpdateClientPermissions(client);
NewMessage("Gave the client \"" + client.Name + "\" the permission to use console commands " + string.Join(", ", grantedCommands.Select(c => c.names[0])) + ".", Color.White); NewMessage("Gave the client \"" + client.Name + "\" the permission to use console commands " + string.Join(", ", grantedCommands.Select(c => c.names[0])) + ".", Color.White);
}); }, args, 2);
}); });
AssignOnExecute("revokecommandperm", (string[] args) => AssignOnExecute("revokecommandperm", (string[] args) =>
@@ -558,11 +564,10 @@ namespace Barotrauma
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
ThrowError("Client id \"" + id + "\" not found."); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -587,7 +592,7 @@ namespace Barotrauma
client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Except(revokedCommands).ToList()); client.SetPermissions(client.Permissions, client.PermittedConsoleCommands.Except(revokedCommands).ToList());
GameMain.Server.UpdateClientPermissions(client); GameMain.Server.UpdateClientPermissions(client);
NewMessage("Revoked \"" + client.Name + "\"'s permission to use the console commands " + string.Join(", ", revokedCommands.Select(c => c.names[0])) + ".", Color.White); NewMessage("Revoked \"" + client.Name + "\"'s permission to use the console commands " + string.Join(", ", revokedCommands.Select(c => c.names[0])) + ".", Color.White);
}); }, args, 2);
}); });
AssignOnExecute("showperm", (string[] args) => AssignOnExecute("showperm", (string[] args) =>
@@ -599,11 +604,10 @@ namespace Barotrauma
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
ThrowError("Client id \"" + id + "\" not found."); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -1571,11 +1575,10 @@ namespace Barotrauma
{ {
if (args.Length < 2) return; if (args.Length < 2) return;
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
GameMain.Server.SendConsoleMessage("Client id \"" + id + "\" not found.", senderClient); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -1600,11 +1603,10 @@ namespace Barotrauma
{ {
if (args.Length < 2) return; if (args.Length < 2) return;
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
GameMain.Server.SendConsoleMessage("Client id \"" + id + "\" not found.", senderClient); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -1629,11 +1631,10 @@ namespace Barotrauma
{ {
if (args.Length < 2) return; if (args.Length < 2) return;
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
GameMain.Server.SendConsoleMessage("Client id \"" + id + "\" not found.", senderClient); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -1658,11 +1659,10 @@ namespace Barotrauma
{ {
if (args.Length < 2) return; if (args.Length < 2) return;
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
GameMain.Server.SendConsoleMessage("Client id \"" + id + "\" not found.", senderClient); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -1696,11 +1696,10 @@ namespace Barotrauma
{ {
if (args.Length < 2) return; if (args.Length < 2) return;
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
GameMain.Server.SendConsoleMessage("Client id \"" + id + "\" not found.", senderClient); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -1738,11 +1737,10 @@ namespace Barotrauma
return; return;
} }
int.TryParse(args[0], out int id); var client = FindClient(args[0]);
var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
if (client == null) if (client == null)
{ {
GameMain.Server.SendConsoleMessage("Client id \"" + id + "\" not found.", senderClient); ThrowError("Client \"" + args[0] + "\" not found.");
return; return;
} }
@@ -107,6 +107,7 @@ namespace Barotrauma
ScriptedEventSet.LoadPrefabs(); ScriptedEventSet.LoadPrefabs();
AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions)); AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings));
StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure)); StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure));
ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item)); ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item));
JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs)); JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));
@@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) public void ServerRead(ClientNetObject type, IReadMessage msg, Client c)
{ {
bool autoTemp = msg.ReadBoolean(); bool autoTemp = msg.ReadBoolean();
bool shutDown = msg.ReadBoolean(); bool powerOn = msg.ReadBoolean();
float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8); float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
float turbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8); float turbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8);
@@ -24,10 +24,10 @@ namespace Barotrauma.Items.Components
if (!autoTemp && AutoTemp) blameOnBroken = c; if (!autoTemp && AutoTemp) blameOnBroken = c;
if (turbineOutput < targetTurbineOutput) blameOnBroken = c; if (turbineOutput < targetTurbineOutput) blameOnBroken = c;
if (fissionRate > targetFissionRate) blameOnBroken = c; if (fissionRate > targetFissionRate) blameOnBroken = c;
if (!this._powerOn && shutDown) blameOnBroken = c; if (!_powerOn && powerOn) blameOnBroken = c;
AutoTemp = autoTemp; AutoTemp = autoTemp;
this._powerOn = shutDown; _powerOn = powerOn;
targetFissionRate = fissionRate; targetFissionRate = fissionRate;
targetTurbineOutput = turbineOutput; targetTurbineOutput = turbineOutput;
@@ -327,6 +327,12 @@ namespace Barotrauma.Networking
#endif #endif
if (!started) { return; } if (!started) { return; }
if (OwnerConnection != null && ChildServerRelay.HasShutDown)
{
Disconnect();
return;
}
base.Update(deltaTime); base.Update(deltaTime);
fileSender.Update(deltaTime); fileSender.Update(deltaTime);
@@ -6,7 +6,7 @@
<RootNamespace>Barotrauma</RootNamespace> <RootNamespace>Barotrauma</RootNamespace>
<Authors>FakeFish, Undertow Games</Authors> <Authors>FakeFish, Undertow Games</Authors>
<Product>Barotrauma Dedicated Server</Product> <Product>Barotrauma Dedicated Server</Product>
<Version>0.9.702.0</Version> <Version>0.9.703.0</Version>
<Copyright>Copyright © FakeFish 2018-2020</Copyright> <Copyright>Copyright © FakeFish 2018-2020</Copyright>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<AssemblyName>DedicatedServer</AssemblyName> <AssemblyName>DedicatedServer</AssemblyName>
@@ -103,6 +103,7 @@
<Text file="Content/Texts/TraditionalChinese/TraditionalChineseVanilla.xml" /> <Text file="Content/Texts/TraditionalChinese/TraditionalChineseVanilla.xml" />
<Text file="Content/Texts/Japanese/JapaneseVanilla.xml" /> <Text file="Content/Texts/Japanese/JapaneseVanilla.xml" />
<Text file="Content/Texts/Turkish/TurkishVanilla.xml" /> <Text file="Content/Texts/Turkish/TurkishVanilla.xml" />
<Text file="Content/Texts/Korean/KoreanVanilla.xml" />
<UIStyle file="Content/UI/style.xml"/> <UIStyle file="Content/UI/style.xml"/>
<Afflictions file="Content/Afflictions.xml"/> <Afflictions file="Content/Afflictions.xml"/>
<Structure file="Content/Map/StructurePrefabs.xml" /> <Structure file="Content/Map/StructurePrefabs.xml" />
@@ -130,10 +131,12 @@
<NPCConversations file="Content/NPCConversations/TraditionalChinese/NpcConversations_TraditionalChinese.xml"/> <NPCConversations file="Content/NPCConversations/TraditionalChinese/NpcConversations_TraditionalChinese.xml"/>
<NPCConversations file="Content/NPCConversations/Japanese/NpcConversations_Japanese.xml"/> <NPCConversations file="Content/NPCConversations/Japanese/NpcConversations_Japanese.xml"/>
<NPCConversations file="Content/NPCConversations/Turkish/NpcConversations_Turkish.xml"/> <NPCConversations file="Content/NPCConversations/Turkish/NpcConversations_Turkish.xml"/>
<NPCConversations file="Content/NPCConversations/Korean/NpcConversations_Korean.xml"/>
<Jobs file="Content/Jobs.xml" /> <Jobs file="Content/Jobs.xml" />
<Orders file="Content/Orders.xml" /> <Orders file="Content/Orders.xml" />
<Sounds file="Content/Sounds/sounds.xml" /> <Sounds file="Content/Sounds/sounds.xml" />
<Tutorials file="Content/Tutorials/Tutorials.xml" /> <Tutorials file="Content/Tutorials/Tutorials.xml" />
<SkillSettings file="Content/SkillSettings.xml" />
<Executable file="Barotrauma" /> <Executable file="Barotrauma" />
<ServerExecutable file="DedicatedServer" /> <ServerExecutable file="DedicatedServer" />
</contentpackage> </contentpackage>
@@ -296,14 +296,14 @@ namespace Barotrauma
} }
float multiplier = MathHelper.Lerp(1, 10, MathHelper.Clamp(collider.LinearVelocity.Length() / 10, 0, 1)); float multiplier = MathHelper.Lerp(1, 10, MathHelper.Clamp(collider.LinearVelocity.Length() / 10, 0, 1));
float targetDistance = collider.GetSize().X * multiplier; float targetDistance = collider.GetSize().X * multiplier;
float horizontalDistance = Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X); float horizontalDistance = Math.Abs(character.WorldPosition.X - currentPath.CurrentNode.WorldPosition.X);
float verticalDistance = Math.Abs(collider.SimPosition.Y - currentPath.CurrentNode.SimPosition.Y); float verticalDistance = Math.Abs(character.WorldPosition.Y - currentPath.CurrentNode.WorldPosition.Y);
if (character.CurrentHull != currentPath.CurrentNode.CurrentHull) if (character.CurrentHull != currentPath.CurrentNode.CurrentHull)
{ {
verticalDistance *= 2; verticalDistance *= 2;
} }
float distance = horizontalDistance + verticalDistance; float distance = horizontalDistance + verticalDistance;
if (distance < targetDistance) if (ConvertUnits.ToSimUnits(distance) < targetDistance)
{ {
currentPath.SkipToNextNode(); currentPath.SkipToNextNode();
} }
@@ -74,6 +74,8 @@ namespace Barotrauma
public readonly Dictionary<string, Sprite> OptionSprites; public readonly Dictionary<string, Sprite> OptionSprites;
public readonly float Weight;
static Order() static Order()
{ {
Prefabs = new Dictionary<string, Order>(); Prefabs = new Dictionary<string, Order>();
@@ -172,6 +174,9 @@ namespace Barotrauma
PrefabList = new List<Order>(Prefabs.Values); PrefabList = new List<Order>(Prefabs.Values);
} }
/// <summary>
/// Constructor for order prefabs
/// </summary>
private Order(XElement orderElement) private Order(XElement orderElement)
{ {
Identifier = orderElement.GetAttributeString("identifier", ""); Identifier = orderElement.GetAttributeString("identifier", "");
@@ -199,6 +204,7 @@ namespace Barotrauma
AppropriateJobs = orderElement.GetAttributeStringArray("appropriatejobs", new string[0]); AppropriateJobs = orderElement.GetAttributeStringArray("appropriatejobs", new string[0]);
Options = orderElement.GetAttributeStringArray("options", new string[0]); Options = orderElement.GetAttributeStringArray("options", new string[0]);
Category = (OrderCategory)Enum.Parse(typeof(OrderCategory), orderElement.GetAttributeString("category", "undefined"), true); Category = (OrderCategory)Enum.Parse(typeof(OrderCategory), orderElement.GetAttributeString("category", "undefined"), true);
Weight = orderElement.GetAttributeFloat(0.0f, "weight");
string translatedOptionNames = TextManager.Get("OrderOptions." + Identifier, true); string translatedOptionNames = TextManager.Get("OrderOptions." + Identifier, true);
if (translatedOptionNames == null) if (translatedOptionNames == null)
@@ -243,6 +249,9 @@ namespace Barotrauma
} }
} }
/// <summary>
/// Constructor for order instances
/// </summary>
public Order(Order prefab, Entity targetEntity, ItemComponent targetItem, Character orderGiver = null) public Order(Order prefab, Entity targetEntity, ItemComponent targetItem, Character orderGiver = null)
{ {
Prefab = prefab; Prefab = prefab;
@@ -257,6 +266,7 @@ namespace Barotrauma
TargetAllCharacters = prefab.TargetAllCharacters; TargetAllCharacters = prefab.TargetAllCharacters;
AppropriateJobs = prefab.AppropriateJobs; AppropriateJobs = prefab.AppropriateJobs;
FadeOutTime = prefab.FadeOutTime; FadeOutTime = prefab.FadeOutTime;
Weight = prefab.Weight;
OrderGiver = orderGiver; OrderGiver = orderGiver;
TargetEntity = targetEntity; TargetEntity = targetEntity;
@@ -1407,7 +1407,7 @@ namespace Barotrauma
target.CharacterHealth.CalculateVitality(); target.CharacterHealth.CalculateVitality();
if (wasCritical && target.Vitality > 0.0f && Timing.TotalTime > lastReviveTime + 10.0f) if (wasCritical && target.Vitality > 0.0f && Timing.TotalTime > lastReviveTime + 10.0f)
{ {
character.Info.IncreaseSkillLevel("medical", 0.5f, character.WorldPosition + Vector2.UnitY * 150.0f); character.Info.IncreaseSkillLevel("medical", SkillSettings.Current.SkillIncreasePerCprRevive, character.WorldPosition + Vector2.UnitY * 150.0f);
SteamAchievementManager.OnCharacterRevived(target, character); SteamAchievementManager.OnCharacterRevived(target, character);
lastReviveTime = (float)Timing.TotalTime; lastReviveTime = (float)Timing.TotalTime;
#if SERVER #if SERVER
@@ -138,6 +138,8 @@ namespace Barotrauma
private readonly List<StatusEffect> statusEffects = new List<StatusEffect>(); private readonly List<StatusEffect> statusEffects = new List<StatusEffect>();
private readonly List<float> speedMultipliers = new List<float>(); private readonly List<float> speedMultipliers = new List<float>();
private float greatestNegativeSpeedMultiplier = 1f;
private float greatestPositiveSpeedMultiplier = 1f;
public Entity ViewTarget public Entity ViewTarget
{ {
@@ -1069,42 +1071,32 @@ namespace Barotrauma
{ {
get get
{ {
if (speedMultipliers.Count == 0) return 1f; return greatestPositiveSpeedMultiplier - (1f - greatestNegativeSpeedMultiplier);
float greatestPositive = 1f;
float greatestNegative = 1f;
for (int i = 0; i < speedMultipliers.Count; i++)
{
float val = speedMultipliers[i];
if (val < 1f)
{
if (val < greatestNegative)
{
greatestNegative = val;
}
}
else
{
if (val > greatestPositive)
{
greatestPositive = val;
}
}
}
return greatestPositive - (1f - greatestNegative);
} }
set }
public void StackSpeedMultiplier(float val)
{
if (val < 1f)
{ {
if (value == 1f) return; if (val < greatestNegativeSpeedMultiplier)
speedMultipliers.Add(value); {
greatestNegativeSpeedMultiplier = val;
}
}
else
{
if (val > greatestPositiveSpeedMultiplier)
{
greatestPositiveSpeedMultiplier = val;
}
} }
} }
public void ResetSpeedMultiplier() public void ResetSpeedMultiplier()
{ {
speedMultipliers.Clear(); greatestPositiveSpeedMultiplier = 1f;
greatestNegativeSpeedMultiplier = 1f;
} }
public float ApplyTemporarySpeedLimits(float speed) public float ApplyTemporarySpeedLimits(float speed)
@@ -1440,6 +1432,7 @@ namespace Barotrauma
public bool HasEquippedItem(Item item) public bool HasEquippedItem(Item item)
{ {
if (Inventory == null) { return false; }
for (int i = 0; i < Inventory.Capacity; i++) for (int i = 0; i < Inventory.Capacity; i++)
{ {
if (Inventory.Items[i] == item && Inventory.SlotTypes[i] != InvSlotType.Any) return true; if (Inventory.Items[i] == item && Inventory.SlotTypes[i] != InvSlotType.Any) return true;
@@ -2339,15 +2332,16 @@ namespace Barotrauma
} }
private readonly List<AIChatMessage> aiChatMessageQueue = new List<AIChatMessage>(); private readonly List<AIChatMessage> aiChatMessageQueue = new List<AIChatMessage>();
private readonly List<AIChatMessage> prevAiChatMessages = new List<AIChatMessage>();
//key = identifier, value = time the message was sent
private readonly Dictionary<string, float> prevAiChatMessages = new Dictionary<string, float>();
public void DisableLine(string identifier) public void DisableLine(string identifier)
{ {
var dummyMsg = new AIChatMessage("", ChatMessageType.Default, identifier) if (!string.IsNullOrEmpty(identifier))
{ {
SendTime = Timing.TotalTime prevAiChatMessages[identifier] = (float)Timing.TotalTime;
}; }
prevAiChatMessages.Add(dummyMsg);
} }
public void Speak(string message, ChatMessageType? messageType = null, float delay = 0.0f, string identifier = "", float minDurationBetweenSimilar = 0.0f) public void Speak(string message, ChatMessageType? messageType = null, float delay = 0.0f, string identifier = "", float minDurationBetweenSimilar = 0.0f)
@@ -2355,10 +2349,15 @@ namespace Barotrauma
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
if (string.IsNullOrEmpty(message)) { return; } if (string.IsNullOrEmpty(message)) { return; }
if (prevAiChatMessages.ContainsKey(identifier) &&
prevAiChatMessages[identifier] < Timing.TotalTime - minDurationBetweenSimilar)
{
prevAiChatMessages.Remove(identifier);
}
//already sent a similar message a moment ago //already sent a similar message a moment ago
if (!string.IsNullOrEmpty(identifier) && minDurationBetweenSimilar > 0.0f && if (!string.IsNullOrEmpty(identifier) && minDurationBetweenSimilar > 0.0f &&
(aiChatMessageQueue.Any(m => m.Identifier == identifier) || (aiChatMessageQueue.Any(m => m.Identifier == identifier) || prevAiChatMessages.ContainsKey(identifier)))
prevAiChatMessages.Any(m => m.Identifier == identifier && m.SendTime > Timing.TotalTime - minDurationBetweenSimilar)))
{ {
return; return;
} }
@@ -2403,15 +2402,25 @@ namespace Barotrauma
{ {
sent.SendTime = Timing.TotalTime; sent.SendTime = Timing.TotalTime;
aiChatMessageQueue.Remove(sent); aiChatMessageQueue.Remove(sent);
prevAiChatMessages.Add(sent); if (!string.IsNullOrEmpty(sent.Identifier))
{
prevAiChatMessages[sent.Identifier] = (float)sent.SendTime;
}
} }
for (int i = prevAiChatMessages.Count - 1; i >= 0; i--) if (prevAiChatMessages.Count > 100)
{ {
if (prevAiChatMessages[i].SendTime < Timing.TotalTime - 60.0f) List<string> toRemove = new List<string>();
foreach (KeyValuePair<string,float> prevMessage in prevAiChatMessages)
{ {
prevAiChatMessages.RemoveRange(0, i + 1); if (prevMessage.Value < Timing.TotalTime - 60.0f)
break; {
toRemove.Add(prevMessage.Key);
}
}
foreach (string identifier in toRemove)
{
prevAiChatMessages.Remove(identifier);
} }
} }
} }
@@ -619,7 +619,7 @@ namespace Barotrauma
{ {
UpdateBleedingProjSpecific((AfflictionBleeding)affliction, targetLimb, deltaTime); UpdateBleedingProjSpecific((AfflictionBleeding)affliction, targetLimb, deltaTime);
} }
Character.SpeedMultiplier = affliction.GetSpeedMultiplier(); Character.StackSpeedMultiplier(affliction.GetSpeedMultiplier());
} }
} }
@@ -638,7 +638,7 @@ namespace Barotrauma
var affliction = afflictions[i]; var affliction = afflictions[i];
affliction.Update(this, null, deltaTime); affliction.Update(this, null, deltaTime);
affliction.DamagePerSecondTimer += deltaTime; affliction.DamagePerSecondTimer += deltaTime;
Character.SpeedMultiplier = affliction.GetSpeedMultiplier(); Character.StackSpeedMultiplier(affliction.GetSpeedMultiplier());
} }
UpdateLimbAfflictionOverlays(); UpdateLimbAfflictionOverlays();
@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
class SkillSettings : ISerializableEntity
{
public static SkillSettings Current
{
get;
private set;
}
[Serialize(4.0f, true)]
public float SingleRoundSkillGainMultiplier { get; set; }
private float skillIncreasePerRepair;
[Serialize(5.0f, true)]
public float SkillIncreasePerRepair
{
get { return skillIncreasePerRepair * GetCurrentSkillGainMultiplier(); }
set { skillIncreasePerRepair = value; }
}
private float skillIncreasePerSabotage;
[Serialize(3.0f, true)]
public float SkillIncreasePerSabotage
{
get { return skillIncreasePerSabotage * GetCurrentSkillGainMultiplier(); }
set { skillIncreasePerSabotage = value; }
}
private float skillIncreasePerCprRevive;
[Serialize(0.5f, true)]
public float SkillIncreasePerCprRevive
{
get { return skillIncreasePerCprRevive * GetCurrentSkillGainMultiplier(); }
set { skillIncreasePerCprRevive = value; }
}
private float skillIncreasePerRepairedStructureDamage;
[Serialize(0.005f, true)]
public float SkillIncreasePerRepairedStructureDamage
{
get { return skillIncreasePerRepairedStructureDamage * GetCurrentSkillGainMultiplier(); }
set { skillIncreasePerRepairedStructureDamage = value; }
}
private float skillIncreasePerSecondWhenSteering;
[Serialize(0.005f, true)]
public float SkillIncreasePerSecondWhenSteering
{
get { return skillIncreasePerSecondWhenSteering * GetCurrentSkillGainMultiplier(); }
set { skillIncreasePerSecondWhenSteering = value; }
}
private float skillIncreasePerFabricatorRequiredSkill;
[Serialize(0.5f, true)]
public float SkillIncreasePerFabricatorRequiredSkill
{
get { return skillIncreasePerFabricatorRequiredSkill * GetCurrentSkillGainMultiplier(); }
set { skillIncreasePerFabricatorRequiredSkill = value; }
}
private SkillSettings(XElement element)
{
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
}
public string Name => "SkillSettings";
public Dictionary<string, SerializableProperty> SerializableProperties
{
get;
set;
}
public static void Load(IEnumerable<ContentFile> files)
{
//reverse order to respect content package load order (last file overrides others)
foreach (ContentFile file in files.Reverse())
{
if (file.Type != ContentType.SkillSettings)
{
throw new ArgumentException();
}
XDocument doc = XMLExtensions.TryLoadXml(file.Path);
if (doc == null) { continue; }
Current = new SkillSettings(doc.Root);
break;
}
if (Current == null)
{
DebugConsole.NewMessage("Now skill settings found in the selected content packages. Using default values.");
Current = new SkillSettings(null);
}
}
private float GetCurrentSkillGainMultiplier()
{
if (GameMain.GameSession?.GameMode is CampaignMode)
{
return 1.0f;
}
else
{
return SingleRoundSkillGainMultiplier;
}
}
}
}
@@ -38,7 +38,8 @@ namespace Barotrauma
UIStyle, UIStyle,
TraitorMissions, TraitorMissions,
EventManagerSettings, EventManagerSettings,
Orders Orders,
SkillSettings
} }
public class ContentPackage public class ContentPackage
@@ -290,11 +290,41 @@ namespace Barotrauma
commands.Add(new Command("startwhenclientsready", "startwhenclientsready [true/false]: Enable or disable automatically starting the round when clients are ready to start.", null)); commands.Add(new Command("startwhenclientsready", "startwhenclientsready [true/false]: Enable or disable automatically starting the round when clients are ready to start.", null));
commands.Add(new Command("giveperm", "giveperm [id]: Grants administrative permissions to the player with the specified client ID.", null)); commands.Add(new Command("giveperm", "giveperm [id]: Grants administrative permissions to the player with the specified client ID.", null,
() =>
{
if (GameMain.NetworkMember == null) return null;
commands.Add(new Command("revokeperm", "revokeperm [id]: Revokes administrative permissions to the player with the specified client ID.", null)); return new string[][]
{
GameMain.NetworkMember.ConnectedClients.Select(c => c.Name).ToArray(),
Enum.GetValues(typeof(ClientPermissions)).Cast<ClientPermissions>().Select(v => v.ToString()).ToArray()
};
}));
commands.Add(new Command("giverank", "giverank [id]: Assigns a specific rank (= a set of administrative permissions) to the player with the specified client ID.", null)); commands.Add(new Command("revokeperm", "revokeperm [id]: Revokes administrative permissions to the player with the specified client ID.", null,
() =>
{
if (GameMain.NetworkMember == null) return null;
return new string[][]
{
GameMain.NetworkMember.ConnectedClients.Select(c => c.Name).ToArray(),
Enum.GetValues(typeof(ClientPermissions)).Cast<ClientPermissions>().Select(v => v.ToString()).ToArray()
};
}));
commands.Add(new Command("giverank", "giverank [id]: Assigns a specific rank (= a set of administrative permissions) to the player with the specified client ID.", null,
() =>
{
if (GameMain.NetworkMember == null) return null;
return new string[][]
{
GameMain.NetworkMember.ConnectedClients.Select(c => c.Name).ToArray(),
PermissionPreset.List.Select(pp => pp.Name).ToArray()
};
}));
commands.Add(new Command("givecommandperm", "givecommandperm [id]: Gives the player with the specified client ID the permission to use the specified console commands.", null)); commands.Add(new Command("givecommandperm", "givecommandperm [id]: Gives the player with the specified client ID the permission to use the specified console commands.", null));
@@ -823,6 +853,7 @@ namespace Barotrauma
var reactor = reactorItem.GetComponent<Reactor>(); var reactor = reactorItem.GetComponent<Reactor>();
reactor.TurbineOutput = power / reactor.MaxPowerOutput * 100.0f; reactor.TurbineOutput = power / reactor.MaxPowerOutput * 100.0f;
reactor.FissionRate = power / reactor.MaxPowerOutput * 100.0f; reactor.FissionRate = power / reactor.MaxPowerOutput * 100.0f;
reactor.PowerOn = true;
reactor.AutoTemp = true; reactor.AutoTemp = true;
#if SERVER #if SERVER
@@ -1514,8 +1545,13 @@ namespace Barotrauma
} }
} }
public static void ShowQuestionPrompt(string question, QuestionCallback onAnswered) public static void ShowQuestionPrompt(string question, QuestionCallback onAnswered, string[] args = null, int argCount = -1)
{ {
if (args != null && args.Length > argCount)
{
onAnswered(args[argCount]);
}
#if CLIENT #if CLIENT
activeQuestionText = new GUITextBlock(new RectTransform(new Point(listBox.Content.Rect.Width, 0), listBox.Content.RectTransform), activeQuestionText = new GUITextBlock(new RectTransform(new Point(listBox.Content.Rect.Width, 0), listBox.Content.RectTransform),
" >>" + question, font: GUI.SmallFont, wrap: true) " >>" + question, font: GUI.SmallFont, wrap: true)
@@ -77,6 +77,12 @@ namespace Barotrauma
Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos); Level.Loaded.TryGetInterestingPosition(true, Level.PositionType.MainPath, Level.Loaded.Size.X * 0.3f, out Vector2 spawnPos);
bool isClient = IsClient; bool isClient = IsClient;
if (monsters.Count > 0)
{
throw new Exception($"monsters.Count > 0 ({monsters.Count})");
}
if (!string.IsNullOrEmpty(monsterFile)) if (!string.IsNullOrEmpty(monsterFile))
{ {
for (int i = 0; i < monsterCount; i++) for (int i = 0; i < monsterCount; i++)
@@ -92,12 +98,22 @@ namespace Barotrauma
} }
} }
if (tempSonarPositions.Count > 0)
{
throw new Exception($"tempSonarPositions.Count > 0 ({tempSonarPositions.Count})");
}
monsters.ForEach(m => m.Enabled = false); monsters.ForEach(m => m.Enabled = false);
SwarmBehavior.CreateSwarm(monsters.Cast<AICharacter>()); SwarmBehavior.CreateSwarm(monsters.Cast<AICharacter>());
for (int i = 0; i < monsters.Count; i++) for (int i = 0; i < monsters.Count; i++)
{ {
tempSonarPositions.Add(spawnPos + Rand.Vector(maxSonarMarkerDistance)); tempSonarPositions.Add(spawnPos + Rand.Vector(maxSonarMarkerDistance));
} }
if (monsters.Count != tempSonarPositions.Count)
{
throw new Exception($"monsters.Count != tempSonarPositions.Count ({monsters.Count} != {tempSonarPositions.Count})");
}
} }
public override void Update(float deltaTime) public override void Update(float deltaTime)
@@ -108,6 +124,16 @@ namespace Barotrauma
//keep sonar markers within maxSonarMarkerDistance from the monster(s) //keep sonar markers within maxSonarMarkerDistance from the monster(s)
for (int i = 0; i < tempSonarPositions.Count; i++) for (int i = 0; i < tempSonarPositions.Count; i++)
{ {
if (monsters.Count != tempSonarPositions.Count)
{
throw new Exception($"monsters.Count != tempSonarPositions.Count ({monsters.Count} != {tempSonarPositions.Count})");
}
if (i < 0 || i >= monsters.Count)
{
throw new Exception($"Index {i} outside of bounds 0-{monsters.Count} ({tempSonarPositions.Count})");
}
if (monsters[i].Removed || monsters[i].IsDead) { continue; } if (monsters[i].Removed || monsters[i].IsDead) { continue; }
Vector2 diff = tempSonarPositions[i] - monsters[i].Position; Vector2 diff = tempSonarPositions[i] - monsters[i].Position;
@@ -148,6 +174,8 @@ namespace Barotrauma
public override void End() public override void End()
{ {
tempSonarPositions.Clear();
monsters.Clear();
if (State < 1) { return; } if (State < 1) { return; }
GiveReward(); GiveReward();
@@ -39,7 +39,7 @@ namespace Barotrauma
private ScriptedEventSet(XElement element, string debugIdentifier) private ScriptedEventSet(XElement element, string debugIdentifier)
{ {
DebugIdentifier = debugIdentifier; DebugIdentifier = element.GetAttributeString("identifier", null) ?? debugIdentifier;
Commonness = new Dictionary<string, float>(); Commonness = new Dictionary<string, float>();
EventPrefabs = new List<ScriptedEventPrefab>(); EventPrefabs = new List<ScriptedEventPrefab>();
ChildSets = new List<ScriptedEventSet>(); ChildSets = new List<ScriptedEventSet>();
@@ -72,7 +72,7 @@ namespace Barotrauma.Items.Components
ApplyStatusEffects(ActionType.OnActive, deltaTime, null); ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
if (powerConsumption <= 0.0f) { Voltage = 1.0f; } if (powerConsumption <= 0.0f) { Voltage = 1.0f; }
progressTimer += deltaTime * Voltage; progressTimer += deltaTime * Math.Min(Voltage, 1.0f);
var targetItem = inputContainer.Inventory.Items.LastOrDefault(i => i != null); var targetItem = inputContainer.Inventory.Items.LastOrDefault(i => i != null);
if (targetItem == null) { return; } if (targetItem == null) { return; }
@@ -10,8 +10,6 @@ namespace Barotrauma.Items.Components
partial class Fabricator : Powered, IServerSerializable, IClientSerializable partial class Fabricator : Powered, IServerSerializable, IClientSerializable
{ {
public const float SkillIncreaseMultiplier = 0.5f;
private readonly List<FabricationRecipe> fabricationRecipes = new List<FabricationRecipe>(); private readonly List<FabricationRecipe> fabricationRecipes = new List<FabricationRecipe>();
private FabricationRecipe fabricatedItem; private FabricationRecipe fabricatedItem;
@@ -130,13 +128,6 @@ namespace Barotrauma.Items.Components
if (selectedItem == null) return; if (selectedItem == null) return;
if (!outputContainer.Inventory.IsEmpty()) return; if (!outputContainer.Inventory.IsEmpty()) return;
#if SERVER
if (user != null)
{
GameServer.Log(user.LogName + " started fabricating " + selectedItem.DisplayName + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
}
#endif
#if CLIENT #if CLIENT
itemList.Enabled = false; itemList.Enabled = false;
activateButton.Text = TextManager.Get("FabricatorCancel"); activateButton.Text = TextManager.Get("FabricatorCancel");
@@ -155,20 +146,19 @@ namespace Barotrauma.Items.Components
currPowerConsumption = powerConsumption; currPowerConsumption = powerConsumption;
currPowerConsumption *= MathHelper.Lerp(1.5f, 1.0f, item.Condition / item.MaxCondition); currPowerConsumption *= MathHelper.Lerp(1.5f, 1.0f, item.Condition / item.MaxCondition);
#if SERVER
if (user != null)
{
GameServer.Log(user.LogName + " started fabricating " + selectedItem.DisplayName + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
}
item.CreateServerEvent(this);
#endif
} }
private void CancelFabricating(Character user = null) private void CancelFabricating(Character user = null)
{ {
#if SERVER if (fabricatedItem == null) { return; }
if (fabricatedItem != null)
{
if (user != null)
{
GameServer.Log(user.LogName + " cancelled the fabrication of " + fabricatedItem.DisplayName + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
}
item.CreateServerEvent(this);
}
#endif
IsActive = false; IsActive = false;
fabricatedItem = null; fabricatedItem = null;
@@ -190,6 +180,13 @@ namespace Barotrauma.Items.Components
inputContainer.Inventory.Locked = false; inputContainer.Inventory.Locked = false;
outputContainer.Inventory.Locked = false; outputContainer.Inventory.Locked = false;
#if SERVER
if (user != null)
{
GameServer.Log(user.LogName + " cancelled the fabrication of " + fabricatedItem.DisplayName + " in " + item.Name, ServerLog.MessageType.ItemInteraction);
}
item.CreateServerEvent(this);
#endif
} }
public override void Update(float deltaTime, Camera cam) public override void Update(float deltaTime, Camera cam)
@@ -215,7 +212,7 @@ namespace Barotrauma.Items.Components
if (powerConsumption <= 0) { Voltage = 1.0f; } if (powerConsumption <= 0) { Voltage = 1.0f; }
timeUntilReady -= deltaTime * Voltage; timeUntilReady -= deltaTime * Math.Min(Voltage, 1.0f);
if (timeUntilReady > 0.0f) { return; } if (timeUntilReady > 0.0f) { return; }
@@ -254,14 +251,15 @@ namespace Barotrauma.Items.Components
{ {
foreach (Skill skill in fabricatedItem.RequiredSkills) foreach (Skill skill in fabricatedItem.RequiredSkills)
{ {
user.Info.IncreaseSkillLevel(skill.Identifier, skill.Level / 100.0f * SkillIncreaseMultiplier, user.WorldPosition + Vector2.UnitY * 150.0f); float userSkill = user.GetSkillLevel(skill.Identifier);
user.Info.IncreaseSkillLevel(
skill.Identifier,
skill.Level * SkillSettings.Current.SkillIncreasePerFabricatorRequiredSkill / Math.Max(userSkill, 1.0f),
user.WorldPosition + Vector2.UnitY * 150.0f);
} }
} }
CancelFabricating(null); CancelFabricating();
#if SERVER
item.CreateServerEvent(this);
#endif
} }
} }
@@ -50,6 +50,7 @@ namespace Barotrauma.Items.Components
private bool _powerOn; private bool _powerOn;
[Serialize(defaultValue: false, isSaveable: true)]
public bool PowerOn public bool PowerOn
{ {
get { return _powerOn; } get { return _powerOn; }
@@ -106,16 +106,18 @@ namespace Barotrauma.Items.Components
get => currentMode; get => currentMode;
set set
{ {
bool changed = currentMode != value;
currentMode = value; currentMode = value;
if (value == Mode.Passive) if (value == Mode.Passive)
{ {
currentPingIndex = -1;
if (item.AiTarget != null) if (item.AiTarget != null)
{ {
item.AiTarget.SectorDegrees = 360.0f; item.AiTarget.SectorDegrees = 360.0f;
} }
} }
#if CLIENT #if CLIENT
if (changed) { prevPassivePingRadius = float.MaxValue; }
UpdateGUIElements(); UpdateGUIElements();
#endif #endif
} }
@@ -263,7 +265,7 @@ namespace Barotrauma.Items.Components
character.Speak(TextManager.GetWithVariables(dialogTag, new string[2] { "[direction]", "[count]" }, character.Speak(TextManager.GetWithVariables(dialogTag, new string[2] { "[direction]", "[count]" },
new string[2] { targetGroup.Key.ToString(), targetGroup.Value.Count.ToString() }, new string[2] { targetGroup.Key.ToString(), targetGroup.Value.Count.ToString() },
new bool[2] { true, false }), null, 0, "sonartarget" + targetGroup.Value[0].ID, 30); new bool[2] { true, false }), null, 0, "sonartarget" + targetGroup.Value[0].ID, 60);
//prevent the character from reporting other targets in the group //prevent the character from reporting other targets in the group
for (int i = 1; i < targetGroup.Value.Count; i++) for (int i = 1; i < targetGroup.Value.Count; i++)
@@ -277,21 +277,25 @@ namespace Barotrauma.Items.Components
ApplyStatusEffects(ActionType.OnActive, deltaTime, null); ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
float userSkill = 0.0f;
if (user != null && (user.SelectedConstruction == item || item.linkedTo.Contains(user.SelectedConstruction)))
{
userSkill = user.GetSkillLevel("helm") / 100.0f;
}
if (AutoPilot) if (AutoPilot)
{ {
UpdateAutoPilot(deltaTime); UpdateAutoPilot(deltaTime);
float userSkill = 0.0f;
if (user != null && (user.SelectedConstruction == item || item.linkedTo.Contains(user.SelectedConstruction)))
{
userSkill = user.GetSkillLevel("helm") / 100.0f;
}
targetVelocity = targetVelocity.ClampLength(MathHelper.Lerp(AutoPilotMaxSpeed, AIPilotMaxSpeed, userSkill) * 100.0f); targetVelocity = targetVelocity.ClampLength(MathHelper.Lerp(AutoPilotMaxSpeed, AIPilotMaxSpeed, userSkill) * 100.0f);
} }
else else
{ {
if (user != null && user.Info != null && user.SelectedConstruction == item) if (user != null && user.Info != null && user.SelectedConstruction == item)
{ {
user.Info.IncreaseSkillLevel("helm", 0.005f * deltaTime, user.WorldPosition + Vector2.UnitY * 150.0f); user.Info.IncreaseSkillLevel(
"helm",
SkillSettings.Current.SkillIncreasePerSecondWhenSteering / Math.Max(userSkill, 1.0f) * deltaTime,
user.WorldPosition + Vector2.UnitY * 150.0f);
} }
Vector2 velocityDiff = steeringInput - targetVelocity; Vector2 velocityDiff = steeringInput - targetVelocity;
@@ -9,9 +9,6 @@ namespace Barotrauma.Items.Components
{ {
partial class Repairable : ItemComponent, IServerSerializable, IClientSerializable partial class Repairable : ItemComponent, IServerSerializable, IClientSerializable
{ {
public static float SkillIncreasePerRepair = 5.0f;
public static float SkillIncreasePerSabotage = 3.0f;
private string header; private string header;
private float deteriorationTimer; private float deteriorationTimer;
@@ -282,7 +279,7 @@ namespace Barotrauma.Items.Components
{ {
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier); float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier, CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier,
SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f), SkillSettings.Current.SkillIncreasePerRepair / Math.Max(characterSkillLevel, 1.0f),
CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f); CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f);
} }
@@ -313,7 +310,7 @@ namespace Barotrauma.Items.Components
{ {
float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier); float characterSkillLevel = CurrentFixer.GetSkillLevel(skill.Identifier);
CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier, CurrentFixer.Info.IncreaseSkillLevel(skill.Identifier,
SkillIncreasePerSabotage / Math.Max(characterSkillLevel, 1.0f), SkillSettings.Current.SkillIncreasePerSabotage / Math.Max(characterSkillLevel, 1.0f),
CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f); CurrentFixer.WorldPosition + Vector2.UnitY * 100.0f);
} }
@@ -83,8 +83,14 @@ namespace Barotrauma.Items.Components
public bool CanReceive(WifiComponent sender) public bool CanReceive(WifiComponent sender)
{ {
if (sender == null || sender.channel != channel) { return false; } if (sender == null || sender.channel != channel) { return false; }
if (sender.TeamID == Character.TeamType.Team1 && TeamID == Character.TeamType.Team2) { return false; }
if (sender.TeamID == Character.TeamType.Team2 && TeamID == Character.TeamType.Team1) { return false; } if (sender.TeamID != Character.TeamType.None && TeamID != Character.TeamType.None)
{
if (sender.TeamID != TeamID)
{
return false;
}
}
if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) { return false; } if (Vector2.DistanceSquared(item.WorldPosition, sender.item.WorldPosition) > sender.range * sender.range) { return false; }
@@ -674,18 +674,30 @@ namespace Barotrauma.Items.Components
public override void FlipX(bool relativeToSub) public override void FlipX(bool relativeToSub)
{ {
Vector2 refPos = item.Submarine == null ?
Vector2.Zero :
item.Position - item.Submarine.HiddenSubPosition;
for (int i = 0; i < nodes.Count; i++) for (int i = 0; i < nodes.Count; i++)
{ {
nodes[i] = new Vector2(-nodes[i].X, nodes[i].Y); nodes[i] = relativeToSub ?
new Vector2(-nodes[i].X, nodes[i].Y) :
new Vector2(refPos.X - (nodes[i].X - refPos.X), nodes[i].Y);
} }
UpdateSections(); UpdateSections();
} }
public override void FlipY(bool relativeToSub) public override void FlipY(bool relativeToSub)
{ {
Vector2 refPos = item.Submarine == null ?
Vector2.Zero :
item.Position - item.Submarine.HiddenSubPosition;
for (int i = 0; i < nodes.Count; i++) for (int i = 0; i < nodes.Count; i++)
{ {
nodes[i] = new Vector2(nodes[i].X, -nodes[i].Y); nodes[i] = relativeToSub ?
new Vector2(nodes[i].X, -nodes[i].Y) :
new Vector2(nodes[i].X, refPos.Y - (nodes[i].Y - refPos.Y));
} }
UpdateSections(); UpdateSections();
} }
@@ -44,15 +44,9 @@ namespace Barotrauma
// Adjustment to match the old size of 75,71 // Adjustment to match the old size of 75,71
SlotSpriteSmall.size = new Vector2(SlotSpriteSmall.SourceRect.Width * 0.5859375f, SlotSpriteSmall.SourceRect.Height * 0.5546875f); SlotSpriteSmall.size = new Vector2(SlotSpriteSmall.SourceRect.Width * 0.5859375f, SlotSpriteSmall.SourceRect.Height * 0.5546875f);
slotSpriteVertical = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(672, 218, 75, 144), null, 0);
slotSpriteHorizontal = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(476, 186, 160, 75), null, 0);
slotSpriteRound = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(681, 373, 58, 64), null, 0);
slotHotkeySprite = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(128, 0, 128, 128), null, 0); slotHotkeySprite = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(128, 0, 128, 128), null, 0);
EquipIndicator = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(673, 182, 73, 27), new Vector2(0.5f, 0.5f), 0); EquipIndicator = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(673, 182, 73, 27), new Vector2(0.5f, 0.5f), 0);
EquipIndicatorHighlight = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(679, 108, 67, 21), new Vector2(0.5f, 0.5f), 0); EquipIndicatorHighlight = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(679, 108, 67, 21), new Vector2(0.5f, 0.5f), 0);
DropIndicator = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(870, 55, 73, 66), new Vector2(0.5f, 0.75f), 0);
DropIndicatorHighlight = new Sprite("Content/UI/inventoryAtlas.png", new Rectangle(946, 54, 73, 66), new Vector2(0.5f, 0.75f), 0);
} }
#endif #endif
} }
@@ -107,19 +107,16 @@ namespace Barotrauma
: this (rectangle, Submarine.MainSub) : this (rectangle, Submarine.MainSub)
{ } { }
public Gap(Rectangle newRect, Submarine submarine) public Gap(Rectangle rect, Submarine submarine)
: this(newRect, newRect.Width < newRect.Height, submarine) : this(rect, rect.Width < rect.Height, submarine)
{ } { }
public Gap(Rectangle newRect, bool isHorizontal, Submarine submarine) public Gap(Rectangle rect, bool isHorizontal, Submarine submarine)
: base(MapEntityPrefab.Find(null, "gap"), submarine) : base(MapEntityPrefab.Find(null, "gap"), submarine)
{ {
rect = newRect; this.rect = rect;
flowForce = Vector2.Zero; flowForce = Vector2.Zero;
IsHorizontal = isHorizontal;
this.IsHorizontal = isHorizontal;
open = 1.0f; open = 1.0f;
FindHulls(); FindHulls();
@@ -131,6 +128,7 @@ namespace Barotrauma
outsideCollisionBlocker.CollisionCategories = Physics.CollisionWall; outsideCollisionBlocker.CollisionCategories = Physics.CollisionWall;
outsideCollisionBlocker.CollidesWith = Physics.CollisionCharacter; outsideCollisionBlocker.CollidesWith = Physics.CollisionCharacter;
outsideCollisionBlocker.Enabled = false; outsideCollisionBlocker.Enabled = false;
Resized += newRect => IsHorizontal = newRect.Width < newRect.Height;
DebugConsole.Log("Created gap (" + ID + ")"); DebugConsole.Log("Created gap (" + ID + ")");
} }
@@ -36,6 +36,8 @@ namespace Barotrauma
//is the mouse inside the rect //is the mouse inside the rect
private bool isHighlighted; private bool isHighlighted;
public event Action<Rectangle> Resized;
public bool IsHighlighted public bool IsHighlighted
{ {
get { return isHighlighted || ExternalHighlight; } get { return isHighlighted || ExternalHighlight; }
@@ -578,6 +580,7 @@ namespace Barotrauma
if (!float.IsNaN(value)) if (!float.IsNaN(value))
{ {
_spriteOverrideDepth = MathHelper.Clamp(value, 0.001f, 0.999f); _spriteOverrideDepth = MathHelper.Clamp(value, 0.001f, 0.999f);
if (this is Item) { _spriteOverrideDepth = Math.Min(_spriteOverrideDepth, 0.9f); }
SpriteDepthOverrideIsSet = true; SpriteDepthOverrideIsSet = true;
} }
} }
@@ -42,9 +42,6 @@ namespace Barotrauma
public const int WallSectionSize = 96; public const int WallSectionSize = 96;
public static List<Structure> WallList = new List<Structure>(); public static List<Structure> WallList = new List<Structure>();
//how much mechanic skill increases per damage removed from the wall by welding
public const float SkillIncreaseMultiplier = 0.005f;
const float LeakThreshold = 0.1f; const float LeakThreshold = 0.1f;
#if CLIENT #if CLIENT
@@ -1008,7 +1005,7 @@ namespace Barotrauma
if (damageDiff < 0.0f) if (damageDiff < 0.0f)
{ {
attacker.Info.IncreaseSkillLevel("mechanical", attacker.Info.IncreaseSkillLevel("mechanical",
-damageDiff * SkillIncreaseMultiplier / Math.Max(attacker.GetSkillLevel("mechanical"), 1.0f), -damageDiff * SkillSettings.Current.SkillIncreasePerRepairedStructureDamage / Math.Max(attacker.GetSkillLevel("mechanical"), 1.0f),
SectionPosition(sectionIndex, true)); SectionPosition(sectionIndex, true));
} }
} }
@@ -949,6 +949,7 @@ namespace Barotrauma
&& !fixture.CollisionCategories.HasFlag(Physics.CollisionWall) && !fixture.CollisionCategories.HasFlag(Physics.CollisionWall)
&& !fixture.CollisionCategories.HasFlag(Physics.CollisionRepair)) { return -1; } && !fixture.CollisionCategories.HasFlag(Physics.CollisionRepair)) { return -1; }
if (ignoreSubs && fixture.Body.UserData is Submarine) { return -1; } if (ignoreSubs && fixture.Body.UserData is Submarine) { return -1; }
if (fixture.Body.UserData as string == "ruinroom") { return -1; }
if (fixture.Body.UserData is Structure structure) if (fixture.Body.UserData is Structure structure)
{ {
if (structure.IsPlatform || structure.StairDirection != Direction.None) { return -1; } if (structure.IsPlatform || structure.StairDirection != Direction.None) { return -1; }
@@ -176,8 +176,16 @@ namespace Barotrauma.Networking
byte[] lengthBytes = new byte[2]; byte[] lengthBytes = new byte[2];
lengthBytes[0] = (byte)(msg.Length & 0xFF); lengthBytes[0] = (byte)(msg.Length & 0xFF);
lengthBytes[1] = (byte)((msg.Length >> 8) & 0xFF); lengthBytes[1] = (byte)((msg.Length >> 8) & 0xFF);
writeStream?.Write(lengthBytes, 0, 2); try
writeStream?.Write(msg, 0, msg.Length); {
writeStream?.Write(lengthBytes, 0, 2);
writeStream?.Write(msg, 0, msg.Length);
}
catch (IOException e)
{
shutDown = true;
break;
}
if (shutDown) { break; } if (shutDown) { break; }
@@ -74,6 +74,17 @@ namespace Barotrauma.Networking
RespawnShuttle.Load(false); RespawnShuttle.Load(false);
RespawnShuttle.PhysicsBody.FarseerBody.OnCollision += OnShuttleCollision; RespawnShuttle.PhysicsBody.FarseerBody.OnCollision += OnShuttleCollision;
//prevent wifi components from communicating between the respawn shuttle and other subs
List<WifiComponent> wifiComponents = new List<WifiComponent>();
foreach (Item item in Item.ItemList)
{
if (item.Submarine == RespawnShuttle) { wifiComponents.AddRange(item.GetComponents<WifiComponent>()); }
}
foreach (WifiComponent wifiComponent in wifiComponents)
{
wifiComponent.TeamID = Character.TeamType.FriendlyNPC;
}
ResetShuttle(); ResetShuttle();
shuttleDoors = new List<Door>(); shuttleDoors = new List<Door>();
@@ -148,10 +148,26 @@ namespace Barotrauma
sw.Stop(); sw.Stop();
GameMain.PerformanceCounter.AddElapsedTicks("LevelUpdate", sw.ElapsedTicks); GameMain.PerformanceCounter.AddElapsedTicks("LevelUpdate", sw.ElapsedTicks);
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction)) if (Character.Controlled != null)
{ {
Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled, (float)deltaTime); if (Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
{
Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
}
if (Character.Controlled.Inventory != null)
{
foreach (Item item in Character.Controlled.Inventory.Items)
{
if (item == null) { continue; }
if (Character.Controlled.HasEquippedItem(item))
{
item.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
}
}
}
} }
sw.Restart(); sw.Restart();
Character.UpdateAll((float)deltaTime, cam); Character.UpdateAll((float)deltaTime, cam);
@@ -520,7 +520,7 @@ namespace Barotrauma
{ if (parentObject is Character character && value is float) { character.LowPassMultiplier = (float)value; return true; } } { if (parentObject is Character character && value is float) { character.LowPassMultiplier = (float)value; return true; } }
break; break;
case "SpeedMultiplier": case "SpeedMultiplier":
{ if (parentObject is Character character && value is float) { character.SpeedMultiplier = (float)value; return true; } } { if (parentObject is Character character && value is float) { character.StackSpeedMultiplier((float)value); return true; } }
break; break;
case "IsOn": case "IsOn":
{ if (parentObject is LightComponent lightComponent && value is bool) { lightComponent.IsOn = (bool)value; return true; } } { if (parentObject is LightComponent lightComponent && value is bool) { lightComponent.IsOn = (bool)value; return true; } }
@@ -35,6 +35,8 @@ public static class AssemblyInfo
#if DEBUG #if DEBUG
retVal = "Debug" + retVal; retVal = "Debug" + retVal;
#elif UNSTABLE
retVal = "Unstable" + retVal;
#else #else
retVal = "Release" + retVal; retVal = "Release" + retVal;
#endif #endif
Binary file not shown.
Binary file not shown.
Binary file not shown.
+33 -3
View File
@@ -1,5 +1,35 @@
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
v0.9.702 (Unstable) v0.9.703.0 (Unstable)
---------------------------------------------------------------------------------------------------------
- Numerous UI fixes (layout improvements, improved scaling on different resolutions, fixed item interface overlaps, text overflow fixes).
- Added Korean translation.
- Numerous fixes to random events to better pace new level dimensions.
- Fixed non-host clients crashing when disconnecting from the server.
- Made giveperm/giverank commands suck less by allowing names, endpoints and SteamIDs instead of clientlist id, and allowing users to skip question prompt by adding rank or perm as a second parameter.
- Fixes to render order oddities (structures with a depth > 0.5 always rendering behind all items, inconsistent render order between sub editor and in-game). Now structures with a depth of >= 0.9 are always behind everything (and visible through the LOS effect), and item's sprite depth is capped to 0.9.
- Fixed engines causing crashes if MinVoltage is set to 0.
- Fixed multiplayer campaign saves appearing in the single player "load game" menu if they're placed in the singleplayer save folder (leading to a crash if a player starts to load the save).
- Fixed fabricator cancellation failing to be communicated under certain circumstances.
- Fixed fabricator an deconstructor operating faster when run on overvoltage, making it possible to fabricate/deconstruct things almost instantaneously by using relays.
- Fixed campaign store filter doing nothing.
- Potentially a fixed race condition when autoupdating Workshop items during loading screen.
- Fixed subinventories not opening when trying to heal an unconscious character.
- Fixed crashing when moving the nodes of a wire that's not connected to anything in the sub editor.
- Fixed inability to drag wires out of the wiring interface (even if they're disconnected from both ends).
- Another fix to inventory items occasionally getting messed up in multiplayer.
- Removed oxygenite shards as a product of deconstructing liquid oxygenite to prevent production loops.
- Fixed sonar showing everything around the sub when sending out a directional ping and switching to passive.
- Fixed inability to drag characters from room to another in alien ruins.
- Fixed excessively large tonic liquid collider.
- Fixed reactor's on/off state not being saved.
- Fixed crashing if a modded UI style contains multiple child styles with the same name.
- Wifi components in the respawn shuttle can't communicate with components in other submarines/shuttles.
- Fixed wire nodes getting misplaced when flipping wires in the sub editor.
- Fixed groups of items that include wires sometimes not getting placed at the position of the cursor when pasting them in the sub editor.
---------------------------------------------------------------------------------------------------------
v0.9.702.0 (Unstable)
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
- UI overhaul - UI overhaul
@@ -25,7 +55,7 @@ v0.9.702 (Unstable)
- Added combat priorities to alien weapons to allow bots to use them. - Added combat priorities to alien weapons to allow bots to use them.
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
v0.9.701 (Unstable) v0.9.701.0 (Unstable)
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
- Fixed SteamP2P server hosting. - Fixed SteamP2P server hosting.
@@ -45,7 +75,7 @@ v0.9.701 (Unstable)
- Fixed sub editor allowing vanilla subs to be deleted. - Fixed sub editor allowing vanilla subs to be deleted.
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
v0.9.700 (Unstable) v0.9.700.0 (Unstable)
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
- Additional logging to diagnose event/entity ID errors: server and clients write a log file with a bunch of debug information the error happens. The files can be found in the ServerLogs folder after the error has occurred. If you get log files, please send them to us to help us diagnose these bugs! - Additional logging to diagnose event/entity ID errors: server and clients write a log file with a bunch of debug information the error happens. The files can be found in the ServerLogs folder after the error has occurred. If you get log files, please send them to us to help us diagnose these bugs!
@@ -56,13 +56,41 @@ namespace Steamworks
#region FunctionMeta #region FunctionMeta
[UnmanagedFunctionPointer( Platform.MemberConvention )] [UnmanagedFunctionPointer( Platform.MemberConvention )]
private delegate HServerListRequest FRequestInternetServerList( IntPtr self, AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse ); private delegate HServerListRequest FRequestInternetServerList( IntPtr self, AppId iApp, IntPtr ppchFilters, uint nFilters, IntPtr pRequestServersResponse );
private FRequestInternetServerList _RequestInternetServerList; private FRequestInternetServerList _RequestInternetServerList;
#endregion #endregion
internal HServerListRequest RequestInternetServerList( AppId iApp, [In,Out] ref MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse ) internal HServerListRequest RequestInternetServerList( AppId iApp, MatchMakingKeyValuePair[] ppchFilters, uint nFilters, IntPtr pRequestServersResponse )
{ {
var returnValue = _RequestInternetServerList( Self, iApp, ref ppchFilters, nFilters, pRequestServersResponse ); int numPtrs = ppchFilters.Length;
if (numPtrs <= 0) { numPtrs = 1; }
IntPtr[] filterPtrs = new IntPtr[numPtrs];
GCHandle?[] filterHandles = new GCHandle?[numPtrs];
for (int i=0;i<numPtrs; i++)
{
if (i < ppchFilters.Length)
{
filterHandles[i] = GCHandle.Alloc(ppchFilters[i], GCHandleType.Pinned);
filterPtrs[i] = filterHandles[i]?.AddrOfPinnedObject() ?? IntPtr.Zero;
}
else
{
filterHandles[i] = null;
filterPtrs[i] = IntPtr.Zero;
}
}
GCHandle arrHandle = GCHandle.Alloc(filterPtrs, GCHandleType.Pinned);
var returnValue = _RequestInternetServerList( Self, iApp, arrHandle.AddrOfPinnedObject(), nFilters, pRequestServersResponse );
arrHandle.Free();
for (int i = 0; i < numPtrs; i++)
{
filterHandles[i]?.Free();
}
return returnValue; return returnValue;
} }
@@ -12,7 +12,7 @@ namespace Steamworks.ServerList
{ {
var filters = GetFilters(); var filters = GetFilters();
request = Internal.RequestInternetServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero ); request = Internal.RequestInternetServerList( AppId.Value, filters, (uint)filters.Length, IntPtr.Zero );
} }
} }
} }