diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj.user b/Barotrauma/BarotraumaClient/LinuxClient.csproj.user
deleted file mode 100644
index 944ec00e2..000000000
--- a/Barotrauma/BarotraumaClient/LinuxClient.csproj.user
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- ShowAllFiles
-
-
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj
index 181d1f112..d21001bd7 100644
--- a/Barotrauma/BarotraumaClient/MacClient.csproj
+++ b/Barotrauma/BarotraumaClient/MacClient.csproj
@@ -1,4 +1,4 @@
-
+
ReleaseMac
@@ -265,24 +265,61 @@
PreserveNewest
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+ Icon.bmp
+
+
diff --git a/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs b/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs
index a62ca56a0..82dea8e96 100644
--- a/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs
+++ b/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.9.0.7")]
-[assembly: AssemblyFileVersion("0.9.0.7")]
+[assembly: AssemblyVersion("0.9.1.0")]
+[assembly: AssemblyFileVersion("0.9.1.0")]
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/HumanoidAnimParams.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/HumanoidAnimParams.cs
deleted file mode 100644
index 74de4a791..000000000
--- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/HumanoidAnimParams.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Xml;
-using System.Xml.Linq;
-
-namespace Barotrauma
-{
- partial class HumanoidAnimParams : ISerializableEntity
- {
- private static GUIListBox editor;
- public static GUIListBox Editor
- {
- get
- {
- if (editor == null)
- {
- editor = new GUIListBox(new RectTransform(new Vector2(0.3f, 1), GUI.Canvas));
- //editor.AddChild(new SerializableEntityEditor(editor.RectTransform, WalkInstance, false, true, elementHeight: 20));
- //editor.AddChild(new SerializableEntityEditor(editor.RectTransform, RunInstance, false, true, elementHeight: 20));
- }
- return editor;
- }
- }
-
-#if FALSE
- //TODO: fix
- public void Save()
- {
- XDocument doc = XMLExtensions.TryLoadXml(filePath);
- if (doc == null || doc.Root == null) return;
-
- SerializableProperty.SerializeProperties(this, doc.Root, true);
-
- XmlWriterSettings settings = new XmlWriterSettings();
- settings.Indent = true;
- settings.OmitXmlDeclaration = true;
- settings.NewLineOnAttributes = true;
-
- using (var writer = XmlWriter.Create(filePath, settings))
- {
- doc.WriteTo(writer);
- writer.Flush();
- }
- }
-#endif
- }
-}
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
index b281ff3bb..5c36aae9e 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
@@ -365,7 +365,7 @@ namespace Barotrauma
{
string chatMessage = CauseOfDeath.Type == CauseOfDeathType.Affliction ?
CauseOfDeath.Affliction.SelfCauseOfDeathDescription :
- TextManager.Get("Self_CauseOfDeathDescription." + CauseOfDeath.Type.ToString());
+ TextManager.Get("Self_CauseOfDeathDescription." + CauseOfDeath.Type.ToString(), fallBackTag: "Self_CauseOfDeathDescription.Damage");
if (GameMain.Client != null) chatMessage += " " + TextManager.Get("DeathChatNotification");
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs
index a38ec2a93..004c074a0 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs
@@ -216,7 +216,7 @@ namespace Barotrauma
Color.LightGreen, Color.Black, 2, GUI.SmallFont);
textPos.Y += offset.Y;
}
- if (character.FocusedCharacter.CharacterHealth.UseHealthWindow)
+ if (character.FocusedCharacter.CharacterHealth.UseHealthWindow && character.CanInteractWith(character.FocusedCharacter, 160f, false))
{
GUI.DrawString(spriteBatch, textPos, GetCachedHudText("HealHint", GameMain.Config.KeyBind(InputType.Health).ToString()),
Color.LightGreen, Color.Black, 2, GUI.SmallFont);
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs
deleted file mode 100644
index becb82d8c..000000000
--- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHealth.cs
+++ /dev/null
@@ -1,1387 +0,0 @@
-using Barotrauma.Items.Components;
-using Barotrauma.Networking;
-using Lidgren.Network;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Xml.Linq;
-
-namespace Barotrauma
-{
- partial class CharacterHealth
- {
- private static bool toggledThisFrame;
-
- private static Sprite damageOverlay;
-
- private static string[] strengthTexts;
-
- private GUIButton cprButton;
-
- private Point screenResolution;
-
- private float uiScale, inventoryScale;
-
- private Alignment alignment = Alignment.Left;
- public Alignment Alignment
- {
- get { return alignment; }
- set
- {
- if (alignment == value) return;
- alignment = value;
- UpdateAlignment();
- }
- }
-
- private GUIButton suicideButton;
-
- // healthbars
- private GUIProgressBar healthBar;
- private GUIProgressBar healthBarShadow;
- private GUIProgressBar healthWindowHealthBar;
- private GUIProgressBar healthWindowHealthBarShadow;
- private float healthShadowSize;
- private float healthShadowDelay;
- private float healthBarPulsateTimer;
- private float healthBarPulsatePhase;
-
- private GUITextBlock characterName;
- private GUIFrame afflictionInfoFrame;
- private GUIListBox afflictionInfoContainer;
- private GUIListBox recommendedTreatmentContainer;
-
- private float bloodParticleTimer;
-
- private GUIFrame healthWindow;
-
- private GUIComponent deadIndicator;
-
- private GUIComponent lowSkillIndicator;
-
- private SpriteSheet limbIndicatorOverlay;
- private float limbIndicatorOverlayAnimState;
-
- private GUIFrame dropItemArea;
-
- private float dropItemAnimDuration = 0.5f;
- private float dropItemAnimTimer;
-
- public Item DroppedItem
- {
- get
- {
- return droppedItem;
- }
- }
- private Item droppedItem;
-
- private GUIComponent draggingMed;
-
- private int highlightedLimbIndex = -1;
- private int selectedLimbIndex = -1;
-
- private float distortTimer;
-
- // 0-1
- private float damageIntensity;
- private float damageIntensityDropdownRate = 0.1f;
-
- public float DamageOverlayTimer { get; private set; }
-
- private static CharacterHealth openHealthWindow;
- public static CharacterHealth OpenHealthWindow
- {
- get
- {
- return openHealthWindow;
- }
- set
- {
- if (openHealthWindow == value) return;
- if (value != null && !value.UseHealthWindow) return;
-
- openHealthWindow = value;
- toggledThisFrame = true;
- if (Character.Controlled == null) { return; }
-
- if (value == null &&
- Character.Controlled?.SelectedCharacter?.CharacterHealth != null &&
- Character.Controlled.SelectedCharacter.CharacterHealth == openHealthWindow &&
- !Character.Controlled.SelectedCharacter.CanInventoryBeAccessed)
- {
- Character.Controlled.DeselectCharacter();
- }
-
- Character.Controlled.ResetInteract = true;
- if (openHealthWindow != null)
- {
- openHealthWindow.characterName.Text = value.Character.Name;
- Character.Controlled.SelectedConstruction = null;
- }
- }
- }
-
- static CharacterHealth()
- {
- damageOverlay = new Sprite("Content/UI/damageOverlay.png", Vector2.Zero);
- }
-
- partial void InitProjSpecific(XElement element, Character character)
- {
- if (strengthTexts == null)
- {
- strengthTexts = new string[]
- {
- TextManager.Get("AfflictionStrengthLow"),
- TextManager.Get("AfflictionStrengthMedium"),
- TextManager.Get("AfflictionStrengthHigh")
- };
- }
-
- character.OnAttacked += OnAttacked;
-
- bool horizontal = HUDLayoutSettings.HealthBarAreaLeft.Width > HUDLayoutSettings.HealthBarAreaLeft.Height;
- healthBar = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
- barSize: 1.0f, color: Color.Green, style: horizontal ? "GUIProgressBar" : "GUIProgressBarVertical")
- {
- IsHorizontal = horizontal
- };
- healthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
- barSize: 1.0f, color: Color.Green, style: horizontal ? "GUIProgressBar" : "GUIProgressBarVertical")
- {
- IsHorizontal = horizontal
- };
- healthShadowSize = 1.0f;
-
- afflictionInfoFrame = new GUIFrame(new RectTransform(new Point(HUDLayoutSettings.HealthWindowAreaLeft.Width / 2, 200), GUI.Canvas));
- var paddedInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), afflictionInfoFrame.RectTransform, Anchor.Center), style: null);
- new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.08f), paddedInfoFrame.RectTransform), "", font: GUI.LargeFont)
- {
- UserData = "selectedlimbname"
- };
-
- afflictionInfoContainer = new GUIListBox(new RectTransform(new Vector2(0.7f, 0.85f), paddedInfoFrame.RectTransform, Anchor.BottomLeft));
-
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.08f), paddedInfoFrame.RectTransform), TextManager.Get("SuitableTreatments"), textAlignment: Alignment.TopRight);
- lowSkillIndicator = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.07f), paddedInfoFrame.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(0.0f, 0.08f) },
- TextManager.Get("LowMedicalSkillWarning"), Color.Orange, textAlignment: Alignment.Center, font: GUI.SmallFont, wrap: true)
- {
- Visible = false
- };
- recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(0.28f, 0.5f), paddedInfoFrame.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(0.0f, 0.15f) })
- {
- Spacing = 10
- };
- dropItemArea = new GUIFrame(new RectTransform(new Vector2(0.28f, 0.3f), paddedInfoFrame.RectTransform, Anchor.BottomRight)
- { RelativeOffset = new Vector2(0.0f, 0.0f) }, style: null)
- {
- ToolTip = TextManager.Get("HealthItemUseTip")
- };
- dropItemArea.RectTransform.NonScaledSize = new Point(dropItemArea.Rect.Width);
-
- string[] healthCircleStyles = new string[] { "HealthCircleInner", "HealthCircleMid", "HealthCircleOuter" };
- foreach (string healthCircleStyle in healthCircleStyles)
- {
- for (int i = 1; i < 4; i++)
- {
- var style = GUI.Style.GetComponentStyle(healthCircleStyle + i);
- if (style != null)
- {
- new GUIImage(new RectTransform(Vector2.One, dropItemArea.RectTransform), healthCircleStyle + i)
- {
- CanBeFocused = false
- };
- }
- }
- }
-
- new GUIImage(new RectTransform(Vector2.One * 0.2f, dropItemArea.RectTransform, Anchor.Center), "HealthCross")
- {
- CanBeFocused = false
- };
-
- healthWindow = new GUIFrame(new RectTransform(new Point(100, 200), GUI.Canvas));
- var paddedHealthWindow = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), healthWindow.RectTransform, Anchor.Center))
- {
- Stretch = true,
- RelativeSpacing = 0.03f
- };
-
- var nameContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedHealthWindow.RectTransform) { MinSize = new Point(0, 20) }, isHorizontal: true)
- {
- Stretch = true
- };
-
- characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.LargeFont)
- {
- AutoScale = true
- };
- new GUICustomComponent(new RectTransform(new Vector2(0.4f, 1.0f), nameContainer.RectTransform),
- onDraw: (spriteBatch, component) =>
- {
- character.Info.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), component.Rect.Width);
- });
-
- new GUICustomComponent(new RectTransform(new Vector2(1.0f, 0.9f), paddedHealthWindow.RectTransform),
- (spriteBatch, component) =>
- {
- DrawHealthWindow(spriteBatch, component.RectTransform.Rect, true, false);
- },
- (deltaTime, component) =>
- {
- UpdateLimbIndicators(deltaTime, component.RectTransform.Rect);
- }
- );
- deadIndicator = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.1f), healthWindow.RectTransform, Anchor.Center),
- text: TextManager.Get("Deceased"), font: GUI.LargeFont, textAlignment: Alignment.Center, wrap: true, style: "GUIToolTip")
- {
- Visible = false,
- CanBeFocused = false
- };
-
- healthWindowHealthBar = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
- barSize: 1.0f, color: Color.Green, style: "GUIProgressBarVertical")
- {
- IsHorizontal = false
- };
- healthWindowHealthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
- barSize: 1.0f, color: Color.Green, style: "GUIProgressBarVertical")
- {
- IsHorizontal = false
- };
- cprButton = new GUIButton(new RectTransform(new Point(80, 80), GUI.Canvas), text: "", style: "CPRButton")
- {
- OnClicked = (button, userData) =>
- {
- Character selectedCharacter = Character.Controlled?.SelectedCharacter;
- if (selectedCharacter == null || (!selectedCharacter.IsUnconscious && selectedCharacter.Stun <= 0.0f)) return false;
-
- Character.Controlled.AnimController.Anim = (Character.Controlled.AnimController.Anim == AnimController.Animation.CPR) ?
- AnimController.Animation.None : AnimController.Animation.CPR;
-
- selectedCharacter.AnimController.ResetPullJoints();
-
- if (GameMain.Client != null)
- {
- GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Treatment });
- }
-
- return true;
- },
- Visible = false
- };
-
- UpdateAlignment();
-
- suicideButton = new GUIButton(new RectTransform(new Vector2(0.06f, 0.02f), GUI.Canvas, Anchor.TopCenter)
- { MinSize = new Point(120, 20), RelativeOffset = new Vector2(0.0f, 0.01f) },
- TextManager.Get("GiveInButton"))
- {
- ToolTip = TextManager.Get(GameMain.NetworkMember == null ? "GiveInHelpSingleplayer" : "GiveInHelpMultiplayer"),
- OnClicked = (button, userData) =>
- {
- GUI.ForceMouseOn(null);
- if (Character.Controlled != null)
- {
- if (GameMain.Client != null)
- {
- GameMain.Client.CreateEntityEvent(Character.Controlled, new object[] { NetEntityEvent.Type.Status });
- }
- else
- {
- var causeOfDeath = GetCauseOfDeath();
- Character.Controlled.Kill(causeOfDeath.First, causeOfDeath.Second);
- Character.Controlled = null;
- }
- }
- return true;
- }
- };
-
- if (element != null)
- {
- foreach (XElement subElement in element.Elements())
- {
- switch (subElement.Name.ToString().ToLowerInvariant())
- {
- case "sprite":
- limbIndicatorOverlay = new SpriteSheet(subElement);
- break;
- }
- }
- }
- }
-
- private void OnAttacked(Character attacker, AttackResult attackResult)
- {
- if (Math.Abs(attackResult.Damage) < 0.01f && attackResult.Afflictions.Count == 0) return;
- DamageOverlayTimer = MathHelper.Clamp(attackResult.Damage / MaxVitality, DamageOverlayTimer, 1.0f);
- if (healthShadowDelay <= 0.0f) healthShadowDelay = 1.0f;
-
- if (healthBarPulsateTimer <= 0.0f) healthBarPulsatePhase = 0.0f;
- healthBarPulsateTimer = 1.0f;
-
- float additionalIntensity = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(0, 0.1f, attackResult.Damage / MaxVitality));
- damageIntensity = MathHelper.Clamp(damageIntensity + additionalIntensity, 0, 1);
- }
-
- private void UpdateAlignment()
- {
- healthBar.RectTransform.RelativeOffset = healthBarShadow.RectTransform.RelativeOffset = Vector2.Zero;
- healthWindowHealthBar.RectTransform.RelativeOffset = healthWindowHealthBarShadow.RectTransform.RelativeOffset = Vector2.Zero;
-
- int healthWindowHealthBarWidth = (int)(40 * GUI.Scale);
-
- if (alignment == Alignment.Left)
- {
- healthBar.RectTransform.SetPosition(Anchor.BottomLeft);
- healthBarShadow.RectTransform.SetPosition(Anchor.BottomLeft);
- healthBar.RectTransform.AbsoluteOffset = healthBarShadow.RectTransform.AbsoluteOffset =
- new Point(HUDLayoutSettings.HealthBarAreaLeft.X, GameMain.GraphicsHeight - HUDLayoutSettings.HealthBarAreaLeft.Bottom);
- healthBar.RectTransform.NonScaledSize = healthBarShadow.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarAreaLeft.Size;
-
- healthWindow.RectTransform.AbsoluteOffset = HUDLayoutSettings.HealthWindowAreaLeft.Location + new Point(healthWindowHealthBarWidth, 0);
- healthWindow.RectTransform.NonScaledSize = new Point(
- HUDLayoutSettings.HealthWindowAreaLeft.Width / 3 - healthWindowHealthBarWidth,
- HUDLayoutSettings.HealthWindowAreaLeft.Height);
-
- afflictionInfoFrame.RectTransform.AbsoluteOffset = new Point(
- healthWindow.Rect.Right,
- HUDLayoutSettings.HealthWindowAreaLeft.Y);
- afflictionInfoFrame.RectTransform.NonScaledSize = new Point(
- (int)(HUDLayoutSettings.HealthWindowAreaLeft.Width * 0.66f),
- (int)(HUDLayoutSettings.HealthWindowAreaLeft.Height));
-
- healthWindowHealthBar.RectTransform.NonScaledSize = healthWindowHealthBarShadow.RectTransform.NonScaledSize =
- new Point(healthWindowHealthBarWidth, healthWindow.Rect.Height);
- healthWindowHealthBar.RectTransform.AbsoluteOffset = healthWindowHealthBarShadow.RectTransform.AbsoluteOffset =
- HUDLayoutSettings.HealthWindowAreaLeft.Location;
-
- int cprButtonSize = (int)(100 * GUI.Scale);
- cprButton.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.HealthWindowAreaLeft.Right, dropItemArea.Rect.Center.Y - cprButtonSize / 2);
- cprButton.RectTransform.NonScaledSize = new Point(cprButtonSize);
- }
- else
- {
- healthBar.RectTransform.SetPosition(Anchor.TopLeft);
- healthBarShadow.RectTransform.SetPosition(Anchor.TopLeft);
- healthBar.RectTransform.AbsoluteOffset = healthBarShadow.RectTransform.AbsoluteOffset =
- HUDLayoutSettings.HealthBarAreaRight.Location;
- healthBar.RectTransform.NonScaledSize = healthBarShadow.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarAreaRight.Size;
-
- healthWindow.RectTransform.AbsoluteOffset = new Point(
- HUDLayoutSettings.HealthWindowAreaRight.X + HUDLayoutSettings.HealthWindowAreaRight.Width / 3 * 2,
- HUDLayoutSettings.HealthWindowAreaRight.Y);
- healthWindow.RectTransform.NonScaledSize = new Point(
- HUDLayoutSettings.HealthWindowAreaRight.Width / 3 - healthWindowHealthBarWidth,
- HUDLayoutSettings.HealthWindowAreaRight.Height);
-
- afflictionInfoFrame.RectTransform.AbsoluteOffset = new Point(
- HUDLayoutSettings.HealthWindowAreaRight.X,
- HUDLayoutSettings.HealthWindowAreaLeft.Y);
- afflictionInfoFrame.RectTransform.NonScaledSize = new Point(
- (int)(HUDLayoutSettings.HealthWindowAreaLeft.Width * 0.66f),
- (int)(HUDLayoutSettings.HealthWindowAreaLeft.Height));
-
- healthWindowHealthBar.RectTransform.NonScaledSize = healthWindowHealthBarShadow.RectTransform.NonScaledSize =
- new Point(healthWindowHealthBarWidth, healthWindow.Rect.Height);
- healthWindowHealthBar.RectTransform.AbsoluteOffset = healthWindowHealthBarShadow.RectTransform.AbsoluteOffset =
- new Point(HUDLayoutSettings.HealthWindowAreaRight.Right - healthWindowHealthBarWidth, HUDLayoutSettings.HealthWindowAreaRight.Y);
-
- int cprButtonSize = (int)(100 * GUI.Scale);
- cprButton.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.HealthWindowAreaRight.X - cprButtonSize, dropItemArea.Rect.Center.Y - cprButtonSize / 2);
- cprButton.RectTransform.NonScaledSize = new Point(cprButtonSize);
- }
-
- dropItemArea.RectTransform.NonScaledSize = new Point(dropItemArea.Rect.Width);
-
- screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
- inventoryScale = Inventory.UIScale;
- uiScale = GUI.Scale;
- }
-
- partial void UpdateOxygenProjSpecific(float prevOxygen)
- {
- if (prevOxygen > 0.0f && OxygenAmount <= 0.0f &&
- Character.Controlled == Character)
- {
- SoundPlayer.PlaySound(Character.Info != null && Character.Info.Gender == Gender.Female ? "drownfemale" : "drownmale");
- }
- }
-
- partial void UpdateBleedingProjSpecific(AfflictionBleeding affliction, Limb targetLimb, float deltaTime)
- {
- bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
- if (bloodParticleTimer <= 0.0f)
- {
- float bloodParticleSize = MathHelper.Lerp(0.5f, 1.0f, affliction.Strength / 100.0f);
- if (!Character.AnimController.InWater) bloodParticleSize *= 2.0f;
- var blood = GameMain.ParticleManager.CreateParticle(
- Character.AnimController.InWater ? "waterblood" : "blooddrop",
- targetLimb.WorldPosition, Rand.Vector(affliction.Strength), 0.0f, Character.AnimController.CurrentHull);
-
- if (blood != null)
- {
- blood.Size *= bloodParticleSize;
- }
- bloodParticleTimer = 1.0f;
- }
- }
-
- public void UpdateHUD(float deltaTime)
- {
- if (GUI.DisableHUD) return;
- if (openHealthWindow != null)
- {
- if (openHealthWindow != Character.Controlled?.CharacterHealth && openHealthWindow != Character.Controlled?.SelectedCharacter?.CharacterHealth)
- {
- openHealthWindow = null;
- return;
- }
- }
-
- if (DamageOverlayTimer > 0.0f)
- {
- DamageOverlayTimer -= deltaTime;
- }
- if (damageIntensity > 0)
- {
- damageIntensity -= deltaTime * damageIntensityDropdownRate;
- if (damageIntensity < 0)
- {
- damageIntensity = 0;
- }
- }
-
- if (healthShadowDelay > 0.0f)
- {
- healthShadowDelay -= deltaTime;
- }
- else
- {
- healthShadowSize = healthBar.BarSize > healthShadowSize ?
- Math.Min(healthShadowSize + deltaTime, healthBar.BarSize) :
- Math.Max(healthShadowSize - deltaTime, healthBar.BarSize);
- }
-
- dropItemArea.Visible = !Character.IsDead;
-
- float blurStrength = 0.0f;
- float distortStrength = 0.0f;
- float distortSpeed = 0.0f;
- float radialDistortStrength = 0.0f;
- float chromaticAberrationStrength = 0.0f;
-
- if (Character.IsUnconscious)
- {
- blurStrength = 1.0f;
- distortSpeed = 1.0f;
- }
- else if (OxygenAmount < 100.0f)
- {
- blurStrength = MathHelper.Lerp(0.5f, 1.0f, 1.0f - Vitality / MaxVitality);
- distortStrength = blurStrength;
- distortSpeed = (blurStrength + 1.0f);
- distortSpeed *= distortSpeed * distortSpeed * distortSpeed;
- }
-
- foreach (Affliction affliction in afflictions)
- {
- distortStrength = Math.Max(distortStrength, affliction.GetScreenDistortStrength());
- blurStrength = Math.Max(blurStrength, affliction.GetScreenBlurStrength());
- radialDistortStrength = Math.Max(radialDistortStrength, affliction.GetRadialDistortStrength());
- chromaticAberrationStrength = Math.Max(chromaticAberrationStrength, affliction.GetChromaticAberrationStrength());
- }
- foreach (LimbHealth limbHealth in limbHealths)
- {
- foreach (Affliction affliction in limbHealth.Afflictions)
- {
- distortStrength = Math.Max(distortStrength, affliction.GetScreenDistortStrength());
- blurStrength = Math.Max(blurStrength, affliction.GetScreenBlurStrength());
- radialDistortStrength = Math.Max(radialDistortStrength, affliction.GetRadialDistortStrength());
- chromaticAberrationStrength = Math.Max(chromaticAberrationStrength, affliction.GetChromaticAberrationStrength());
- }
- }
-
- Character.RadialDistortStrength = radialDistortStrength;
- Character.ChromaticAberrationStrength = chromaticAberrationStrength;
- if (blurStrength > 0.0f)
- {
- distortTimer = (distortTimer + deltaTime * distortSpeed) % MathHelper.TwoPi;
- Character.BlurStrength = (float)(Math.Sin(distortTimer) + 1.5f) * 0.25f * blurStrength;
- Character.DistortStrength = (float)(Math.Sin(distortTimer) + 1.0f) * 0.1f * distortStrength;
- }
- else
- {
- Character.BlurStrength = 0.0f;
- Character.DistortStrength = 0.0f;
- distortTimer = 0.0f;
- }
-
- if (PlayerInput.KeyHit(InputType.Health) && GUI.KeyboardDispatcher.Subscriber == null &&
- Character.AllowInput && Character.FocusedCharacter == null && !toggledThisFrame)
- {
- if (openHealthWindow != null)
- OpenHealthWindow = null;
- else
- OpenHealthWindow = this;
- }
- else if (openHealthWindow == this)
- {
- if (Alignment == Alignment.Right ?
- HUD.CloseHUD(HUDLayoutSettings.HealthWindowAreaRight) :
- HUD.CloseHUD(HUDLayoutSettings.HealthWindowAreaLeft))
- {
- //emulate a Health input to get the character to deselect the item server-side
- Character.Keys[(int)InputType.Health].Hit = true;
- OpenHealthWindow = null;
- }
- }
- toggledThisFrame = false;
-
-
- if (Character.IsDead)
- {
- healthBar.Color = healthWindowHealthBar.Color = Color.Black;
- healthBar.BarSize = healthWindowHealthBar.BarSize = 1.0f;
- }
- else
- {
- healthBar.Color = healthWindowHealthBar.Color = ToolBox.GradientLerp(Vitality / MaxVitality, Color.Red, Color.Orange, Color.Green);
- healthBar.HoverColor = healthWindowHealthBar.HoverColor = healthBar.Color * 2.0f;
- healthBar.BarSize = healthWindowHealthBar.BarSize = (Vitality > 0.0f) ? Vitality / MaxVitality : 1.0f - Vitality / MinVitality;
-
- if (healthBarPulsateTimer > 0.0f)
- {
- //0-1
- float pulsateAmount = (float)(Math.Sin(healthBarPulsatePhase) + 1.0f) / 2.0f;
-
- healthBar.RectTransform.LocalScale = healthBarShadow.RectTransform.LocalScale = new Vector2(1.0f, (1.0f + pulsateAmount * healthBarPulsateTimer * 0.5f));
- healthBarPulsatePhase += deltaTime * 5.0f;
- healthBarPulsateTimer -= deltaTime;
- }
- else
- {
- healthBar.RectTransform.LocalScale = Vector2.One;
- }
- }
-
- if (OpenHealthWindow == this)
- {
- if (Character == Character.Controlled && !Character.AllowInput)
- {
- openHealthWindow = null;
- }
-
- lowSkillIndicator.Visible = Timing.TotalTime % 1.0f < 0.8f && Character.Controlled != null && Character.Controlled.GetSkillLevel("medical") < 50.0f;
-
- float rotationSpeed = 0.25f;
- int i = 0;
- foreach (GUIComponent dropItemIndicator in dropItemArea.Children)
- {
- GUIImage img = dropItemIndicator as GUIImage;
- if (img == null) continue;
-
- img.State = GUI.MouseOn == dropItemArea ? GUIComponent.ComponentState.Hover : GUIComponent.ComponentState.None;
-
- byte alpha = img.Color.A;
- byte hoverAlpha = img.HoverColor.A;
- img.Color = ToolBox.GradientLerp(Vitality / MaxVitality, Color.Red, Color.Orange, Color.Green);
- img.Color = new Color(img.Color.R, img.Color.G, img.Color.B, alpha);
- img.HoverColor = new Color(img.Color.R, img.Color.G, img.Color.B, hoverAlpha);
- img.HoverColor = Color.Lerp(img.HoverColor, Color.White, 0.5f);
-
- if (img.State == GUIComponent.ComponentState.Hover && droppedItem == null)
- {
- dropItemAnimTimer = Math.Min(0.3f, dropItemAnimTimer + deltaTime * 0.5f);
- }
-
- if (i < 4)
- {
- img.Scale = 1.0f - (float)Math.Sin(dropItemAnimTimer / dropItemAnimDuration * MathHelper.TwoPi) * 0.3f;
- }
-
- if (dropItemIndicator == dropItemArea.Children.Last()) break;
- img.Rotation = (img.Rotation + (rotationSpeed + dropItemAnimTimer * 10.0f) * deltaTime) % MathHelper.TwoPi;
- rotationSpeed = (rotationSpeed + 0.3f) % 1.0f;
-
- i++;
- }
-
- Rectangle limbArea = healthWindow.Children.First().Rect;
-
- var highlightedLimb = highlightedLimbIndex < 0 ? null : limbHealths[highlightedLimbIndex];
- if (highlightedLimb == null && selectedLimbIndex < 0)
- {
- // If no limb is selected or highlighted, select the one with the most critical afflictions.
- var affliction = GetAllAfflictions(a => a.Prefab.IndicatorLimb != LimbType.None)
- .OrderByDescending(a => a.DamagePerSecond)
- .ThenByDescending(a => a.Strength).FirstOrDefault();
- var limbHealth = GetMathingLimbHealth(affliction);
- if (limbHealth != null)
- {
- selectedLimbIndex = limbHealths.IndexOf(limbHealth);
- }
- }
- UpdateAfflictionContainer(selectedLimbIndex < 0 ? highlightedLimb : limbHealths[selectedLimbIndex]);
-
- if (Inventory.draggingItem != null)
- {
- if (highlightedLimbIndex > -1)
- {
- selectedLimbIndex = highlightedLimbIndex;
- }
- }
-
- if (draggingMed != null)
- {
- if (!PlayerInput.LeftButtonHeld())
- {
- OnItemDropped(draggingMed.UserData as Item, ignoreMousePos: false);
- draggingMed = null;
- }
- }
-
- /*if (GUI.MouseOn?.UserData is Affliction affliction)
- {
- ShowAfflictionInfo(affliction, afflictionInfoContainer);
- }*/
-
- if (dropItemAnimTimer > 0.0f)
- {
- dropItemAnimTimer -= deltaTime;
- if (dropItemAnimTimer <= 0.0f) droppedItem = null;
- }
- }
- else
- {
- if (openHealthWindow != null && Character != Character.Controlled && Character != Character.Controlled?.SelectedCharacter)
- {
- openHealthWindow = null;
- }
- highlightedLimbIndex = -1;
- }
-
- Rectangle hoverArea = alignment == Alignment.Left ?
- Rectangle.Union(HUDLayoutSettings.AfflictionAreaLeft, HUDLayoutSettings.HealthBarAreaLeft) :
- Rectangle.Union(HUDLayoutSettings.AfflictionAreaRight, HUDLayoutSettings.HealthBarAreaRight);
-
- if (Character.AllowInput && UseHealthWindow && hoverArea.Contains(PlayerInput.MousePosition) && Inventory.SelectedSlot == null)
- {
- healthBar.State = GUIComponent.ComponentState.Hover;
- if (PlayerInput.LeftButtonClicked())
- {
- OpenHealthWindow = openHealthWindow == this ? null : this;
- }
- }
- else
- {
- healthBar.State = GUIComponent.ComponentState.None;
- }
-
- suicideButton.Visible = Character == Character.Controlled && Character.IsUnconscious && !Character.IsDead;
-
- cprButton.Visible =
- Character == Character.Controlled?.SelectedCharacter
- && (Character.IsUnconscious || Character.Stun > 0.0f)
- && !Character.IsDead
- && openHealthWindow == this;
-
- deadIndicator.Visible = Character.IsDead;
- }
-
- public void AddToGUIUpdateList()
- {
- if (GUI.DisableHUD) return;
- if (OpenHealthWindow == this)
- {
- //afflictionContainer.AddToGUIUpdateList();
- afflictionInfoFrame.AddToGUIUpdateList();
- healthWindow.AddToGUIUpdateList();
- healthWindowHealthBarShadow.AddToGUIUpdateList();
- healthWindowHealthBar.AddToGUIUpdateList();
- }
- else if (Character.Controlled == Character)
- {
- healthBarShadow.AddToGUIUpdateList();
- healthBar.AddToGUIUpdateList();
- }
- if (suicideButton.Visible && Character == Character.Controlled) suicideButton.AddToGUIUpdateList();
- if (cprButton != null && cprButton.Visible) cprButton.AddToGUIUpdateList();
- }
-
- public void DrawHUD(SpriteBatch spriteBatch)
- {
- if (GUI.DisableHUD) return;
- if (GameMain.GraphicsWidth != screenResolution.X ||
- GameMain.GraphicsHeight != screenResolution.Y ||
- Math.Abs(inventoryScale - Inventory.UIScale) > 0.01f ||
- Math.Abs(uiScale - GUI.Scale) > 0.01f)
- {
- UpdateAlignment();
- }
-
- float damageOverlayAlpha = DamageOverlayTimer;
- if (Vitality < MaxVitality * 0.1f)
- {
- damageOverlayAlpha = Math.Max(1.0f - (Vitality / maxVitality * 10.0f), damageOverlayAlpha);
- }
- else
- {
- float pulsateAmount = (float)(Math.Sin(healthBarPulsatePhase) + 1.0f) / 2.0f;
- damageOverlayAlpha = pulsateAmount * healthBarPulsateTimer * damageIntensity;
- }
-
- if (damageOverlayAlpha > 0.0f)
- {
- damageOverlay.Draw(spriteBatch, Vector2.Zero, Color.White * damageOverlayAlpha, Vector2.Zero, 0.0f,
- new Vector2(GameMain.GraphicsWidth / damageOverlay.size.X, GameMain.GraphicsHeight / damageOverlay.size.Y));
- }
-
- if (Character.Inventory != null)
- {
- if (Character.Inventory.CurrentLayout == CharacterInventory.Layout.Right)
- {
- //move the healthbar on top of the inventory slots
- healthBar.RectTransform.ScreenSpaceOffset = new Point(
- (GameMain.GraphicsWidth - HUDLayoutSettings.Padding) - HUDLayoutSettings.HealthBarAreaRight.Right,
- HUDLayoutSettings.HealthBarAreaRight.Y - (int)(Character.Inventory.SlotPositions.Max(s => s.Y) + Inventory.EquipIndicator.size.Y * Inventory.UIScale * 2) - HUDLayoutSettings.HealthBarAreaRight.Height);
- healthBarShadow.RectTransform.ScreenSpaceOffset = healthBar.RectTransform.ScreenSpaceOffset;
- }
- else
- {
- healthBar.RectTransform.ScreenSpaceOffset = healthBarShadow.RectTransform.ScreenSpaceOffset = Point.Zero;
- }
- }
-
- DrawStatusHUD(spriteBatch);
- }
-
- public void DrawStatusHUD(SpriteBatch spriteBatch)
- {
- //Rectangle interactArea = healthBar.Rect;
- if (openHealthWindow != this)
- {
- List> statusIcons = new List>();
- if (Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 5.0f)
- statusIcons.Add(new Pair(pressureAffliction, TextManager.Get("PressureHUDWarning")));
- if (Character.CurrentHull != null && Character.OxygenAvailable < LowOxygenThreshold && oxygenLowAffliction.Strength < oxygenLowAffliction.Prefab.ShowIconThreshold)
- statusIcons.Add(new Pair(oxygenLowAffliction, TextManager.Get("OxygenHUDWarning")));
-
- var allAfflictions = GetAllAfflictions(true);
- foreach (Affliction affliction in allAfflictions)
- {
- if (affliction.Strength < affliction.Prefab.ShowIconThreshold || affliction.Prefab.Icon == null) continue;
- statusIcons.Add(new Pair(affliction, affliction.Prefab.Name));
- }
-
- Pair highlightedIcon = null;
- Vector2 highlightedIconPos = Vector2.Zero;
- Rectangle afflictionArea = alignment == Alignment.Left ? HUDLayoutSettings.AfflictionAreaLeft : HUDLayoutSettings.AfflictionAreaRight;
- Point pos = afflictionArea.Location + healthBar.RectTransform.ScreenSpaceOffset;
-
- bool horizontal = afflictionArea.Width > afflictionArea.Height;
- int iconSize = horizontal ? afflictionArea.Height : afflictionArea.Width;
-
- foreach (Pair statusIcon in statusIcons)
- {
- Rectangle afflictionIconRect = new Rectangle(pos, new Point(iconSize));
- if (afflictionIconRect.Contains(PlayerInput.MousePosition))
- {
- highlightedIcon = statusIcon;
- highlightedIconPos = afflictionIconRect.Center.ToVector2();
- }
-
- if (statusIcon.First.DamagePerSecond > 1.0f)
- {
- Rectangle glowRect = afflictionIconRect;
- glowRect.Inflate((int)(25 * GUI.Scale), (int)(25 * GUI.Scale));
- var glow = GUI.Style.GetComponentStyle("OuterGlow");
- glow.Sprites[GUIComponent.ComponentState.None][0].Draw(
- spriteBatch, glowRect,
- Color.Red * (float)((Math.Sin(statusIcon.First.DamagePerSecondTimer * MathHelper.TwoPi - MathHelper.PiOver2) + 1.0f) * 0.5f));
- }
-
- var slot = GUI.Style.GetComponentStyle("AfflictionIconSlot");
- slot.Sprites[highlightedIcon == statusIcon ? GUIComponent.ComponentState.Hover : GUIComponent.ComponentState.None][0].Draw(
- spriteBatch, afflictionIconRect,
- highlightedIcon == statusIcon ? slot.HoverColor : slot.Color);
-
-
- statusIcon.First.Prefab.Icon?.Draw(spriteBatch,
- pos.ToVector2(),
- highlightedIcon == statusIcon ? statusIcon.First.Prefab.IconColor : statusIcon.First.Prefab.IconColor * 0.8f,
- rotate: 0,
- scale: iconSize / statusIcon.First.Prefab.Icon.size.X);
-
- if (horizontal)
- pos.X += iconSize + (int)(5 * GUI.Scale);
- else
- pos.Y += iconSize + (int)(5 * GUI.Scale);
- }
-
- if (highlightedIcon != null)
- {
- GUI.DrawString(spriteBatch,
- alignment == Alignment.Left ? highlightedIconPos + new Vector2(60 * GUI.Scale, 5) : highlightedIconPos + new Vector2(-10.0f - GUI.Font.MeasureString(highlightedIcon.Second).X, 5),
- highlightedIcon.Second,
- Color.White * 0.8f, Color.Black * 0.5f);
- }
-
- if (Vitality > 0.0f)
- {
- float currHealth = healthBar.BarSize;
- Color prevColor = healthBar.Color;
- healthBarShadow.BarSize = healthShadowSize;
- healthBarShadow.Color = Color.Red;
- healthBarShadow.Visible = true;
- healthBar.BarSize = currHealth;
- healthBar.Color = prevColor;
- }
- else
- {
- healthBarShadow.Visible = false;
- }
- }
- else
- {
- if (Vitality > 0.0f)
- {
- float currHealth = healthWindowHealthBar.BarSize;
- Color prevColor = healthWindowHealthBar.Color;
- healthWindowHealthBarShadow.BarSize = healthShadowSize;
- healthWindowHealthBarShadow.Color = Color.Red;
- healthWindowHealthBarShadow.Visible = true;
- healthWindowHealthBar.BarSize = currHealth;
- healthWindowHealthBar.Color = prevColor;
- }
- else
- {
- healthWindowHealthBarShadow.Visible = false;
- }
- }
- }
-
- private void UpdateAfflictionContainer(LimbHealth selectedLimb)
- {
- ((GUITextBlock)afflictionInfoContainer.Parent.GetChildByUserData("selectedlimbname")).Text = selectedLimb == null ? "" : selectedLimb.Name;
-
- if (selectedLimb == null)
- {
- afflictionInfoContainer.Content.ClearChildren();
- return;
- }
- var currentAfflictions = GetMatchingAfflictions(selectedLimb, a => a.Strength >= a.Prefab.ShowIconThreshold);
- var displayedAfflictions = afflictionInfoContainer.Content.Children.Select(c => c.UserData as Affliction);
- if (currentAfflictions.Any(a => !displayedAfflictions.Contains(a)) ||
- displayedAfflictions.Any(a => !currentAfflictions.Contains(a)))
- {
- CreateAfflictionInfos(currentAfflictions);
- }
-
- UpdateAfflictionInfos(displayedAfflictions);
- }
-
- private void CreateAfflictionInfos(IEnumerable afflictions)
- {
- afflictionInfoContainer.Content.ClearChildren();
- recommendedTreatmentContainer.Content.ClearChildren();
-
- float characterSkillLevel = Character.Controlled == null ? 0.0f : Character.Controlled.GetSkillLevel("medical");
-
- //random variance is 200% when the skill is 0
- //no random variance if the skill is 50 or more
- float randomVariance = MathHelper.Lerp(2.0f, 0.0f, characterSkillLevel / 50.0f);
-
- //key = item identifier
- //float = suitability
- Dictionary treatmentSuitability = new Dictionary();
- float minSuitability = -10, maxSuitability = 10;
- foreach (Affliction affliction in afflictions)
- {
- foreach (KeyValuePair treatment in affliction.Prefab.TreatmentSuitability)
- {
- if (!treatmentSuitability.ContainsKey(treatment.Key))
- {
- treatmentSuitability[treatment.Key] = treatment.Value * affliction.Strength;
- }
- else
- {
- treatmentSuitability[treatment.Key] += treatment.Value * affliction.Strength;
- }
- minSuitability = Math.Min(treatmentSuitability[treatment.Key], minSuitability);
- maxSuitability = Math.Max(treatmentSuitability[treatment.Key], maxSuitability);
- }
- }
- //normalize the suitabilities to a range of 0 to 1
- foreach (string treatment in treatmentSuitability.Keys.ToList())
- {
- treatmentSuitability[treatment] = (treatmentSuitability[treatment] - minSuitability) / (maxSuitability - minSuitability);
- //lerp towards a random value if the medical skill is low
- treatmentSuitability[treatment] = MathHelper.Lerp(treatmentSuitability[treatment], Rand.Range(0.0f, 1.0f), randomVariance);
- }
-
- foreach (Affliction affliction in afflictions)
- {
- var child = new GUILayoutGroup(new RectTransform(Vector2.One * 0.95f, afflictionInfoContainer.Content.RectTransform, Anchor.TopCenter))
- {
- Stretch = true,
- RelativeSpacing = 0.02f,
- UserData = affliction
- };
-
- var headerContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), child.RectTransform), isHorizontal: true)
- {
- Stretch = true,
- UserData = "header"
- };
-
- new GUIImage(new RectTransform(new Vector2(0.15f, 1.0f), headerContainer.RectTransform), affliction.Prefab.Icon, scaleToFit: true)
- {
- Color = affliction.Prefab.IconColor
- };
-
- var labelContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 1.0f), headerContainer.RectTransform), isHorizontal: true)
- {
- Stretch = true,
- AbsoluteSpacing = 10,
- UserData = "label"
- };
- var afflictionName = new GUITextBlock(new RectTransform(new Vector2(0.65f, 1.0f), labelContainer.RectTransform), affliction.Prefab.Name, textAlignment: Alignment.CenterLeft, font: GUI.LargeFont);
- var afflictionStrength = new GUITextBlock(new RectTransform(new Vector2(0.35f, 0.6f), labelContainer.RectTransform), "", textAlignment: Alignment.TopRight, font: GUI.LargeFont)
- {
- Padding = Vector4.Zero,
- UserData = "strength"
- };
- var vitality = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), labelContainer.RectTransform, Anchor.BottomRight), "", textAlignment: Alignment.BottomRight)
- {
- IgnoreLayoutGroups = true,
- UserData = "vitality"
- };
-
- var description = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), child.RectTransform),
- affliction.Prefab.Description, textAlignment: Alignment.TopLeft, wrap: true);
- if (description.Font.MeasureString(description.WrappedText).Y > description.Rect.Height)
- {
- description.Font = GUI.SmallFont;
- }
- description.RectTransform.Resize(new Point(description.Rect.Width, (int)(description.TextSize.Y + 10)));
- child.RectTransform.Resize(new Point(child.Rect.Width, child.Children.Sum(c => c.Rect.Height)));
- child.Recalculate();
- afflictionStrength.AutoScale = true;
- afflictionName.AutoScale = true;
- vitality.AutoDraw = true;
- }
-
- List> treatmentSuitabilities = treatmentSuitability.OrderByDescending(t => t.Value).ToList();
-
- foreach (KeyValuePair treatment in treatmentSuitabilities)
- {
- ItemPrefab item = MapEntityPrefab.Find(name: null, identifier: treatment.Key, showErrorMessages: false) as ItemPrefab;
- if (item == null) continue;
- int slotSize = (int)(recommendedTreatmentContainer.Content.Rect.Width * 0.8f);
-
- var itemSlot = new GUIButton(new RectTransform(new Point(slotSize), recommendedTreatmentContainer.Content.RectTransform, Anchor.TopCenter),
- text: "", style: "InventorySlotSmall")
- {
- UserData = item
- };
- itemSlot.Color = ToolBox.GradientLerp(treatment.Value, Color.Red, Color.White, Color.LightGreen);
-
- Sprite itemSprite = item.InventoryIcon ?? item.sprite;
- 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),
- itemSprite, scaleToFit: true)
- {
- CanBeFocused = false,
- Color = itemColor,
- HoverColor = itemColor,
- SelectedColor = itemColor
- };
- itemSlot.ToolTip = item.Name + "\n" + item.Description;
- }
-
- afflictionInfoContainer.Content.RectTransform.SortChildren((r1, r2) =>
- {
- var first = r1.GUIComponent.UserData as Affliction;
- var second = r2.GUIComponent.UserData as Affliction;
- int dmgPerSecond = Math.Sign(second.DamagePerSecond - first.DamagePerSecond);
- return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(second.Strength - first.Strength);
- });
-
- //afflictionInfoContainer.Content.RectTransform.SortChildren((r1, r2) =>
- //{
- // return Math.Sign(((Affliction)r2.GUIComponent.UserData).GetVitalityDecrease(this) - ((Affliction)r1.GUIComponent.UserData).GetVitalityDecrease(this));
- //});
- }
-
- private void UpdateAfflictionInfos(IEnumerable afflictions)
- {
- foreach (Affliction affliction in afflictions)
- {
- var child = afflictionInfoContainer.Content.FindChild(affliction);
- var headerContainer = child.GetChildByUserData("header");
- var labelContainer = headerContainer.GetChildByUserData("label");
- var strengthText = labelContainer.GetChildByUserData("strength") as GUITextBlock;
-
- strengthText.Text = strengthTexts[
- MathHelper.Clamp((int)Math.Floor((affliction.Strength / affliction.Prefab.MaxStrength) * strengthTexts.Length), 0, strengthTexts.Length - 1)];
-
- strengthText.TextColor = ToolBox.GradientLerp(
- affliction.Strength / affliction.Prefab.MaxStrength,
- Color.Yellow, Color.Orange, Color.Red);
-
- var vitalityText = labelContainer.GetChildByUserData("vitality") as GUITextBlock;
- int vitalityDecrease = (int)affliction.GetVitalityDecrease(this);
- if (vitalityDecrease == 0)
- {
- vitalityText.Visible = false;
- }
- else
- {
- vitalityText.Visible = true;
- vitalityText.Text = TextManager.Get("Vitality") + " -" + vitalityDecrease;
- vitalityText.TextColor = vitalityDecrease <= 0 ? Color.LightGreen :
- Color.Lerp(Color.Orange, Color.Red, affliction.Strength / affliction.Prefab.MaxStrength);
- }
- }
- }
-
- public bool OnItemDropped(Item item, bool ignoreMousePos)
- {
- //items can be dropped outside the health window
- if (!ignoreMousePos &&
- !healthWindow.Rect.Contains(PlayerInput.MousePosition) &&
- !afflictionInfoFrame.Rect.Contains(PlayerInput.MousePosition))
- {
- return false;
- }
-
- //can't apply treatment to dead characters
- if (Character.IsDead) return true;
- if (item == null || !item.UseInHealthInterface) return true;
- if (!ignoreMousePos)
- {
- if (highlightedLimbIndex > -1)
- {
- selectedLimbIndex = highlightedLimbIndex;
- }
- else if (!dropItemArea.Rect.Contains(PlayerInput.MousePosition))
- {
- return true;
- }
- }
-
- Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == selectedLimbIndex);
-
- item.ApplyTreatment(Character.Controlled, Character, targetLimb);
-
- dropItemAnimTimer = dropItemAnimDuration;
- droppedItem = item;
- return true;
- }
-
- private List- GetAvailableMedicalItems()
- {
- List
- allInventoryItems = new List
- ();
- allInventoryItems.AddRange(Character.Inventory.Items);
- if (Character.SelectedCharacter?.Inventory != null && Character.CanAccessInventory(Character.SelectedCharacter.Inventory))
- {
- allInventoryItems.AddRange(Character.SelectedCharacter.Inventory.Items);
- }
- if (Character.SelectedBy?.Inventory != null)
- {
- allInventoryItems.AddRange(Character.SelectedBy.Inventory.Items);
- }
-
- List
- medicalItems = new List
- ();
- foreach (Item item in allInventoryItems)
- {
- if (item == null) continue;
-
- var containedItems = item.ContainedItems;
- if (containedItems != null)
- {
- foreach (Item containedItem in containedItems)
- {
- if (containedItem == null) continue;
- if (!containedItem.HasTag("medical") && !containedItem.HasTag("chem")) continue;
- medicalItems.Add(containedItem);
- }
- }
-
- if (!item.HasTag("medical") && !item.HasTag("chem")) continue;
- medicalItems.Add(item);
- }
-
- return medicalItems.Distinct().ToList();
- }
-
- private void UpdateLimbIndicators(float deltaTime, Rectangle drawArea)
- {
- limbIndicatorOverlayAnimState += deltaTime * 8.0f;
-
- highlightedLimbIndex = -1;
- int i = 0;
- foreach (LimbHealth limbHealth in limbHealths)
- {
- if (limbHealth.IndicatorSprite == null) continue;
-
- float scale = Math.Min(drawArea.Width / (float)limbHealth.IndicatorSprite.SourceRect.Width, drawArea.Height / (float)limbHealth.IndicatorSprite.SourceRect.Height);
-
- Rectangle highlightArea = GetLimbHighlightArea(limbHealth, drawArea);
-
- if (highlightArea.Contains(PlayerInput.MousePosition))
- {
- highlightedLimbIndex = i;
- }
- i++;
- }
-
- if (PlayerInput.LeftButtonClicked() && highlightedLimbIndex > -1)
- {
- selectedLimbIndex = highlightedLimbIndex;
- //afflictionContainer.ClearChildren();
- afflictionInfoContainer.ClearChildren();
- }
- }
-
- private void DrawHealthWindow(SpriteBatch spriteBatch, Rectangle drawArea, bool allowHighlight, bool highlightAll)
- {
- if (Character.Removed) { return; }
-
- int i = 0;
- foreach (LimbHealth limbHealth in limbHealths)
- {
- if (limbHealth.IndicatorSprite == null) continue;
-
- float damageLerp = limbHealth.TotalDamage > 0.0f ? MathHelper.Lerp(0.2f, 1.0f, limbHealth.TotalDamage / 100.0f) : 0.0f;
- Color color = Character.IsDead ?
- Color.Lerp(Color.Black, new Color(150, 100, 100), damageLerp) :
- ToolBox.GradientLerp(damageLerp, Color.Green, Color.Orange, Color.Red);
- float scale = Math.Min(drawArea.Width / (float)limbHealth.IndicatorSprite.SourceRect.Width, drawArea.Height / (float)limbHealth.IndicatorSprite.SourceRect.Height);
-
- if (((i == highlightedLimbIndex || i == selectedLimbIndex) && allowHighlight) || highlightAll)
- {
- color = Color.Lerp(color, Color.White, 0.5f);
- }
-
- limbHealth.IndicatorSprite.Draw(spriteBatch,
- drawArea.Center.ToVector2(), color,
- limbHealth.IndicatorSprite.Origin,
- 0, scale);
- i++;
- }
-
- spriteBatch.End();
- spriteBatch.Begin(SpriteSortMode.Deferred, Lights.CustomBlendStates.Multiplicative);
-
- float overlayScale = Math.Min(
- drawArea.Width / (float)limbIndicatorOverlay.FrameSize.X,
- drawArea.Height / (float)limbIndicatorOverlay.FrameSize.Y);
-
- int frame = 0;
- int frameCount = 17;
- if (limbIndicatorOverlayAnimState >= frameCount * 2) limbIndicatorOverlayAnimState = 0.0f;
- if (limbIndicatorOverlayAnimState < frameCount)
- {
- frame = (int)limbIndicatorOverlayAnimState;
- }
- else
- {
- frame = frameCount - (int)(limbIndicatorOverlayAnimState - (frameCount - 1));
- }
-
- limbIndicatorOverlay.Draw(spriteBatch, frame, drawArea.Center.ToVector2(), Color.Gray, origin: limbIndicatorOverlay.FrameSize.ToVector2() / 2, rotate: 0.0f,
- scale: Vector2.One * overlayScale);
-
- spriteBatch.End();
- spriteBatch.Begin(SpriteSortMode.Deferred, blendState: BlendState.AlphaBlend, rasterizerState: GameMain.ScissorTestEnable);
-
- i = 0;
- foreach (LimbHealth limbHealth in limbHealths)
- {
- if (limbHealth.IndicatorSprite == null) continue;
- float scale = Math.Min(drawArea.Width / (float)limbHealth.IndicatorSprite.SourceRect.Width, drawArea.Height / (float)limbHealth.IndicatorSprite.SourceRect.Height);
-
- Rectangle highlightArea = new Rectangle(
- (int)(drawArea.Center.X - (limbHealth.IndicatorSprite.Texture.Width / 2 - limbHealth.HighlightArea.X) * scale),
- (int)(drawArea.Center.Y - (limbHealth.IndicatorSprite.Texture.Height / 2 - limbHealth.HighlightArea.Y) * scale),
- (int)(limbHealth.HighlightArea.Width * scale),
- (int)(limbHealth.HighlightArea.Height * scale));
-
- if (selectedLimbIndex == i)
- {
- if (alignment == Alignment.Left)
- {
- GUI.DrawLine(spriteBatch,
- highlightArea.Center.ToVector2(),
- afflictionInfoContainer.Parent.Rect.Location.ToVector2() + Vector2.UnitY * 20,
- Color.LightBlue * 0.3f, 0, 4);
- }
- else
- {
- GUI.DrawLine(spriteBatch,
- highlightArea.Center.ToVector2(),
- new Vector2(afflictionInfoContainer.Parent.Rect.Right, afflictionInfoContainer.Parent.Rect.Y + 20),
- Color.LightBlue * 0.3f, 0, 4);
- }
- }
-
- var slot = GUI.Style.GetComponentStyle("AfflictionIconSlot");
-
- float iconScale = 0.3f * scale;
- Vector2 iconPos = highlightArea.Center.ToVector2();
- foreach (Affliction affliction in limbHealth.Afflictions)
- {
- DrawLimbAfflictionIcon(spriteBatch, affliction, slot, iconScale, ref iconPos);
- }
-
- foreach (Affliction affliction in afflictions)
- {
- Limb indicatorLimb = Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb);
- if (indicatorLimb != null && indicatorLimb.HealthIndex == i)
- {
- DrawLimbAfflictionIcon(spriteBatch, affliction, slot, iconScale, ref iconPos);
- }
- }
- i++;
- }
-
- if (draggingMed != null)
- {
- GUIImage itemImage = draggingMed.GetChild();
- float scale = Math.Min(40.0f / itemImage.Sprite.size.X, 40.0f / itemImage.Sprite.size.Y);
- itemImage.Sprite.Draw(spriteBatch, PlayerInput.MousePosition, itemImage.Color, 0, scale);
- }
-
- if (dropItemAnimTimer > 0.0f && droppedItem?.Prefab.InventoryIcon != null)
- {
- var droppedItemSprite = droppedItem.Prefab.InventoryIcon ?? droppedItem.Sprite;
- droppedItemSprite.Draw(spriteBatch, dropItemArea.Rect.Center.ToVector2(),
- droppedItemSprite == droppedItem.Sprite ? droppedItem.GetSpriteColor() : droppedItem.GetInventoryIconColor(),
- origin: droppedItemSprite.size / 2,
- scale: MathHelper.SmoothStep(0.0f, 100.0f / droppedItemSprite.size.Length(), dropItemAnimTimer / dropItemAnimDuration));
- }
- }
-
- private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, GUIComponentStyle slotStyle, float iconScale, ref Vector2 iconPos)
- {
- if (affliction.Strength < affliction.Prefab.ShowIconThreshold) return;
- Vector2 iconSize = (affliction.Prefab.Icon.size * iconScale);
-
- //afflictions that have a strength of less than 10 are faded out slightly
- float alpha = MathHelper.Lerp(0.3f, 1.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, affliction.Prefab.IconColor * alpha, 0, iconScale);
- iconPos += new Vector2(10.0f, 20.0f) * iconScale;
- }
-
- private Rectangle GetLimbHighlightArea(LimbHealth limbHealth, Rectangle drawArea)
- {
- float scale = Math.Min(drawArea.Width / (float)limbHealth.IndicatorSprite.SourceRect.Width, drawArea.Height / (float)limbHealth.IndicatorSprite.SourceRect.Height);
- return new Rectangle(
- (int)(drawArea.Center.X - (limbHealth.IndicatorSprite.Texture.Width / 2 - limbHealth.HighlightArea.X) * scale),
- (int)(drawArea.Center.Y - (limbHealth.IndicatorSprite.Texture.Height / 2 - limbHealth.HighlightArea.Y) * scale),
- (int)(limbHealth.HighlightArea.Width * scale),
- (int)(limbHealth.HighlightArea.Height * scale));
- }
-
- public void ClientRead(NetBuffer inc)
- {
- List> newAfflictions = new List>();
-
- byte afflictionCount = inc.ReadByte();
- for (int i = 0; i < afflictionCount; i++)
- {
- AfflictionPrefab afflictionPrefab = AfflictionPrefab.List[inc.ReadRangedInteger(0, AfflictionPrefab.List.Count - 1)];
- float afflictionStrength = inc.ReadRangedSingle(0.0f, afflictionPrefab.MaxStrength, 8);
-
- newAfflictions.Add(new Pair(afflictionPrefab, afflictionStrength));
- }
-
- foreach (Affliction affliction in afflictions)
- {
- //deactivate afflictions that weren't included in the network message
- if (!newAfflictions.Any(a => a.First == affliction.Prefab))
- {
- affliction.Strength = 0.0f;
- }
- }
-
- foreach (Pair newAffliction in newAfflictions)
- {
- Affliction existingAffliction = afflictions.Find(a => a.Prefab == newAffliction.First);
- if (existingAffliction == null)
- {
- afflictions.Add(newAffliction.First.Instantiate(newAffliction.Second));
- }
- else
- {
- existingAffliction.Strength = newAffliction.Second;
- if (existingAffliction == stunAffliction) Character.SetStun(existingAffliction.Strength, true, true);
- }
- }
-
- List> newLimbAfflictions = new List>();
- byte limbAfflictionCount = inc.ReadByte();
- for (int i = 0; i < limbAfflictionCount; i++)
- {
- int limbIndex = inc.ReadRangedInteger(0, limbHealths.Count - 1);
- AfflictionPrefab afflictionPrefab = AfflictionPrefab.List[inc.ReadRangedInteger(0, AfflictionPrefab.List.Count - 1)];
- float afflictionStrength = inc.ReadRangedSingle(0.0f, afflictionPrefab.MaxStrength, 8);
-
- newLimbAfflictions.Add(new Triplet(limbHealths[limbIndex], afflictionPrefab, afflictionStrength));
- }
-
- foreach (LimbHealth limbHealth in limbHealths)
- {
- foreach (Affliction affliction in limbHealth.Afflictions)
- {
- //deactivate afflictions that weren't included in the network message
- if (!newLimbAfflictions.Any(a => a.First == limbHealth && a.Second == affliction.Prefab))
- {
- affliction.Strength = 0.0f;
- }
- }
-
- foreach (Triplet newAffliction in newLimbAfflictions)
- {
- if (newAffliction.First != limbHealth) continue;
- Affliction existingAffliction = limbHealth.Afflictions.Find(a => a.Prefab == newAffliction.Second);
- if (existingAffliction == null)
- {
- limbHealth.Afflictions.Add(newAffliction.Second.Instantiate(newAffliction.Third));
- }
- else
- {
- existingAffliction.Strength = newAffliction.Third;
- }
- }
- }
- }
-
- partial void RemoveProjSpecific()
- {
- foreach (LimbHealth limbHealth in limbHealths)
- {
- if (limbHealth.IndicatorSprite != null)
- {
- limbHealth.IndicatorSprite.Remove();
- limbHealth.IndicatorSprite = null;
- }
- }
-
- limbIndicatorOverlay?.Remove();
- limbIndicatorOverlay = null;
- }
- }
-}
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs
index a3d57f795..846e82d39 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs
@@ -449,12 +449,11 @@ namespace Barotrauma
{
float depth = ActiveSprite.Depth - 0.0000015f;
- // TODO: enable when the damage overlay textures have been remade.
- //DamagedSprite.Draw(spriteBatch,
- // new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
- // color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin,
- // -body.DrawRotation,
- // 1.0f, spriteEffect, depth);
+ DamagedSprite.Draw(spriteBatch,
+ new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
+ color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin,
+ -body.DrawRotation,
+ 1.0f, spriteEffect, depth);
}
if (GameMain.DebugDraw)
diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs
index 88f7a7f29..17fc3b0f6 100644
--- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs
+++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs
@@ -206,6 +206,7 @@ namespace Barotrauma
case "togglehud":
case "toggleupperhud":
case "togglecharacternames":
+ case "fpscounter":
return true;
default:
return client.HasConsoleCommandPermission(command);
@@ -1509,7 +1510,7 @@ namespace Barotrauma
return;
}
RagdollParams ragdollParams = character.AnimController.RagdollParams;
- ragdollParams.LimbScale = value;
+ ragdollParams.LimbScale = MathHelper.Clamp(value, RagdollParams.MIN_SCALE, RagdollParams.MAX_SCALE);
var pos = character.WorldPosition;
character.AnimController.Recreate();
character.TeleportTo(pos);
@@ -1534,7 +1535,7 @@ namespace Barotrauma
return;
}
RagdollParams ragdollParams = character.AnimController.RagdollParams;
- ragdollParams.JointScale = value;
+ ragdollParams.JointScale = MathHelper.Clamp(value, RagdollParams.MIN_SCALE, RagdollParams.MAX_SCALE);
var pos = character.WorldPosition;
character.AnimController.Recreate();
character.TeleportTo(pos);
@@ -1559,8 +1560,8 @@ namespace Barotrauma
return;
}
RagdollParams ragdollParams = character.AnimController.RagdollParams;
- ragdollParams.LimbScale = value;
- ragdollParams.JointScale = value;
+ ragdollParams.LimbScale = MathHelper.Clamp(value, RagdollParams.MIN_SCALE, RagdollParams.MAX_SCALE);
+ ragdollParams.JointScale = MathHelper.Clamp(value, RagdollParams.MIN_SCALE, RagdollParams.MAX_SCALE);
var pos = character.WorldPosition;
character.AnimController.Recreate();
character.TeleportTo(pos);
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
index f5d362374..3418d020e 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
@@ -1394,8 +1394,8 @@ namespace Barotrauma
Vector2 moveAmount = centerDiff == Point.Zero ? Rand.Vector(1.0f) : Vector2.Normalize(centerDiff.ToVector2());
//make sure we don't move the interfaces out of the screen
- Vector2 moveAmount1 = ClampMoveAmount(rect1, area, moveAmount * 10.0f * rect1Area / (rect1Area + rect2Area));
- Vector2 moveAmount2 = ClampMoveAmount(rect2, area, -moveAmount * 10.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));
//move by 10 units in the desired direction and repeat until nothing overlaps
//(or after 100 iterations, in which case we'll just give up and let them overlap)
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs
index 6cdba8652..c2f8351bc 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs
@@ -148,7 +148,14 @@ namespace Barotrauma
//find the parent GUIListBox highest in the hierarchy
for (int i = parentHierarchy.Count - 1; i >= 0; i--)
{
- if (parentHierarchy[i].GUIComponent is GUIListBox) return parentHierarchy[i];
+ if (parentHierarchy[i].GUIComponent is GUIListBox)
+ {
+ if (parentHierarchy[i].Parent != null && parentHierarchy[i].Parent.GUIComponent != null)
+ {
+ return parentHierarchy[i].Parent;
+ }
+ return parentHierarchy[i];
+ }
}
//or just go with the direct parent if there are no listboxes in the hierarchy
parentHierarchy.Clear();
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs
index 27743748b..9817060fd 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIImage.cs
@@ -57,8 +57,8 @@ namespace Barotrauma
}
}
- public GUIImage(RectTransform rectT, string style)
- : this(rectT, null, null, false, style)
+ public GUIImage(RectTransform rectT, string style, bool scaleToFit = false)
+ : this(rectT, null, null, scaleToFit, style)
{
}
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs
index dbd796825..ca436e624 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUINumberInput.cs
@@ -131,13 +131,13 @@ namespace Barotrauma
private float pressedDelay = 0.5f;
private bool IsPressedTimerRunning { get { return pressedTimer > 0; } }
- public GUINumberInput(RectTransform rectT, NumberType inputType, string style = "", Alignment textAlignment = Alignment.Center) : base(style, rectT)
+ public GUINumberInput(RectTransform rectT, NumberType inputType, string style = "", Alignment textAlignment = Alignment.Center, float? relativeButtonAreaWidth = null) : base(style, rectT)
{
LayoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, rectT), isHorizontal: true) { Stretch = true };
- float relativeButtonAreaWidth = MathHelper.Clamp(Rect.Height / (float)Rect.Width, 0.1f, 0.5f);
+ float _relativeButtonAreaWidth = relativeButtonAreaWidth ?? MathHelper.Clamp(Rect.Height / (float)Rect.Width, 0.1f, 0.5f);
- TextBox = new GUITextBox(new RectTransform(new Vector2(1.0f - relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform), textAlignment: textAlignment, style: style)
+ TextBox = new GUITextBox(new RectTransform(new Vector2(1.0f - _relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform), textAlignment: textAlignment, style: style)
{
ClampText = false,
// For some reason the caret in the number inputs is dimmer than it should.
@@ -146,7 +146,12 @@ namespace Barotrauma
CaretColor = Color.White
};
TextBox.OnTextChanged += TextChanged;
- var buttonArea = new GUIFrame(new RectTransform(new Vector2(relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight) { MinSize = new Point(Rect.Height, 0) }, style: null);
+ var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
+ if (!relativeButtonAreaWidth.HasValue)
+ {
+ // Not sure what's the point of this
+ buttonArea.RectTransform.MinSize = new Point(Rect.Height, 0);
+ }
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), "+");
PlusButton.OnButtonDown += () =>
{
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIScrollBar.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIScrollBar.cs
index 02856e82d..5f6f443c8 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUIScrollBar.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIScrollBar.cs
@@ -246,14 +246,12 @@ namespace Barotrauma
private bool SelectBar()
{
- if (!enabled) return false;
- // This doesn't work
- if (barSize == 1.0f) return false;
+ if (!enabled || !PlayerInput.LeftButtonDown()) { return false; }
+ if (barSize >= 1.0f) { return false; }
draggingBar = this;
return true;
-
}
public void MoveButton(Vector2 moveAmount)
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs
index 780264181..26fe1031b 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIStyle.cs
@@ -40,6 +40,9 @@ namespace Barotrauma
{
ToolBox.IsProperFilenameCase(file);
doc = XDocument.Load(file, LoadOptions.SetBaseUri);
+ if (doc == null) { throw new Exception("doc is null"); }
+ if (doc.Root == null) { throw new Exception("doc.Root is null"); }
+ if (doc.Root.Elements() == null) { throw new Exception("doc.Root.Elements() is null"); }
}
catch (Exception e)
{
@@ -113,26 +116,34 @@ namespace Barotrauma
private void RescaleFonts()
{
+ if (configElement == null) { return; }
+ if (configElement.Elements() == null) { return; }
foreach (XElement subElement in configElement.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "font":
+ if (Font == null) { continue; }
Font.Size = GetFontSize(subElement);
break;
case "smallfont":
+ if (SmallFont == null) { continue; }
SmallFont.Size = GetFontSize(subElement);
break;
case "largefont":
+ if (LargeFont == null) { continue; }
LargeFont.Size = GetFontSize(subElement);
break;
case "objectivetitle":
+ if (ObjectiveTitleFont == null) { continue; }
ObjectiveTitleFont.Size = GetFontSize(subElement);
break;
case "objectivename":
+ if (ObjectiveNameFont == null) { continue; }
ObjectiveNameFont.Size = GetFontSize(subElement);
break;
case "videotitle":
+ if (VideoTitleFont == null) { continue; }
VideoTitleFont.Size = GetFontSize(subElement);
break;
}
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs
index 8692bf140..f6699c4f7 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs
@@ -389,7 +389,7 @@ namespace Barotrauma
public static void AutoScaleAndNormalize(IEnumerable textBlocks)
{
if (!textBlocks.Any()) { return; }
- float minScale = textBlocks.First().TextScale;
+ float minScale = Math.Max(textBlocks.First().TextScale, 1.0f);
foreach (GUITextBlock textBlock in textBlocks)
{
textBlock.AutoScale = true;
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs
index 06e197eeb..dd572c229 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITickBox.cs
@@ -41,7 +41,28 @@ namespace Barotrauma
OnSelected?.Invoke(this);
}
}
-
+
+ private Color? defaultTextColor;
+
+ public override bool Enabled
+ {
+ get
+ {
+ return enabled;
+ }
+
+ set
+ {
+ if (value == enabled) { return; }
+ enabled = value;
+ if (color.A == 0)
+ {
+ if (defaultTextColor == null) { defaultTextColor = TextBlock.TextColor; }
+ TextBlock.TextColor = enabled ? defaultTextColor.Value : defaultTextColor.Value * 0.5f;
+ }
+ }
+ }
+
public Color TextColor
{
get { return text.TextColor; }
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/ParamsEditor.cs b/Barotrauma/BarotraumaClient/Source/GUI/ParamsEditor.cs
index 591c9ff1b..461a52fc7 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/ParamsEditor.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/ParamsEditor.cs
@@ -19,6 +19,7 @@ namespace Barotrauma
}
}
+ public GUIComponent Parent { get; private set; }
public GUIListBox EditorBox { get; private set; }
///
/// Uses Linq queries. Don't use too frequently or reimplement.
@@ -29,13 +30,12 @@ namespace Barotrauma
public GUIListBox CreateEditorBox(RectTransform rectT = null)
{
- rectT = rectT ?? new RectTransform(new Vector2(0.25f, 0.95f), GUI.Canvas) { MinSize = new Point(340, GameMain.GraphicsHeight) };
+ rectT = rectT ?? new RectTransform(new Vector2(0.25f, 1f), GUI.Canvas) { MinSize = new Point(340, GameMain.GraphicsHeight) };
rectT.SetPosition(Anchor.TopRight);
- rectT.RelativeOffset = new Vector2(0.16f, 0);
- EditorBox = new GUIListBox(rectT)
+ Parent = new GUIFrame(rectT, null, new Color(20, 20, 20, 255));
+ EditorBox = new GUIListBox(new RectTransform(Vector2.One * 0.98f, rectT, Anchor.Center), color: Color.Black, style: null)
{
- Spacing = 10,
- Color = Color.Black
+ Spacing = 10
};
return EditorBox;
}
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/SpriteSheetPlayer.cs b/Barotrauma/BarotraumaClient/Source/GUI/SpriteSheetPlayer.cs
deleted file mode 100644
index f533b7a1e..000000000
--- a/Barotrauma/BarotraumaClient/Source/GUI/SpriteSheetPlayer.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using System;
-using System.Xml.Linq;
-using System.Collections.Generic;
-
-namespace Barotrauma
-{
- class SpriteSheetPlayer
- {
- private SpriteSheet[] playingSheets;
- private SpriteSheet currentSheet;
- private List preloadedSheets;
-
- private GUIFrame background, videoFrame;
- private GUITextBlock title;
- private GUICustomComponent sheetView;
-
- private float totalElapsed = 0;
- private float animationSpeed = 0.1f;
- private float loopTimer = 0.0f;
- private float loopDelay = 0.0f;
-
- private int currentSheetIndex = 0;
- private int currentFrameIndex = 0;
-
- private Color backgroundColor = new Color(0f, 0f, 0f, 1f);
- private Action callbackOnStop;
-
- private bool isPlaying;
- public bool IsPlaying
- {
- get { return isPlaying; }
- private set
- {
- if (isPlaying == value) return;
- isPlaying = value;
- }
- }
-
- private readonly Vector2 defaultResolution = new Vector2(520, 300);
- private readonly int borderSize = 20;
-
- private class PreloadedContent
- {
- public string ContentName;
- public string ContentTag;
- public SpriteSheet[] Sheets;
-
- public PreloadedContent(string name, string tag, SpriteSheet[] sheets)
- {
- ContentName = name;
- ContentTag = tag;
- Sheets = sheets;
- }
- }
-
- public SpriteSheetPlayer()
- {
- int width = (int)defaultResolution.X;
- int height = (int)defaultResolution.Y;
-
- background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor);
- videoFrame = new GUIFrame(new RectTransform(new Point(width + borderSize, height + borderSize), background.RectTransform, Anchor.Center), "SonarFrame");
- sheetView = new GUICustomComponent(new RectTransform(new Point(width, height), videoFrame.RectTransform, Anchor.Center),
- (spriteBatch, guiCustomComponent) => { DrawSheetView(spriteBatch, guiCustomComponent.Rect); }, UpdateSheetView);
- title = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), videoFrame.RectTransform, Anchor.TopCenter, Pivot.BottomCenter), string.Empty, font: GUI.LargeFont, textAlignment: Alignment.Center);
-
- preloadedSheets = new List();
- }
-
- public void PreloadContent(string contentPath, string contentTag, string contentId, XElement contentElement)
- {
- if (preloadedSheets.Find(s => s.ContentName == contentId) != null) return; // Already loaded
- preloadedSheets.Add(new PreloadedContent(contentId, contentTag, CreateSpriteSheets(contentPath, contentElement)));
- }
-
- public void RemoveAllPreloaded()
- {
- if (preloadedSheets == null || preloadedSheets.Count == 0) return;
-
- for (int i = 0; i < preloadedSheets.Count; i++)
- {
- for (int j = 0; j < preloadedSheets[i].Sheets.Length; j++)
- {
- preloadedSheets[i].Sheets[j].Remove();
- }
- }
-
- preloadedSheets.Clear();
- }
-
- public void RemovePreloadedByTag(string tag)
- {
- if (preloadedSheets == null || preloadedSheets.Count == 0) return;
-
- for (int i = 0; i < preloadedSheets.Count; i++)
- {
- if (preloadedSheets[i].ContentTag != tag) continue;
- for (int j = 0; j < preloadedSheets[i].Sheets.Length; j++)
- {
- preloadedSheets[i].Sheets[j].Remove();
- }
-
- preloadedSheets[i] = null;
- preloadedSheets.RemoveAt(i);
- i--;
- }
- }
-
- public void Play()
- {
- isPlaying = true;
- }
-
- public void Stop()
- {
- isPlaying = false;
- }
-
- private bool OKButtonClicked(GUIButton button, object userData)
- {
- Stop();
- callbackOnStop?.Invoke();
- return true;
- }
-
- public void AddToGUIUpdateList()
- {
- if (!isPlaying) return;
- background.AddToGUIUpdateList();
- }
-
- public void LoadContent(string contentPath, XElement videoElement, string contentId, bool startPlayback, bool hasButton, Action callback = null)
- {
- totalElapsed = loopTimer = 0.0f;
- animationSpeed = videoElement.GetAttributeFloat("animationspeed", 0.1f);
- loopDelay = videoElement.GetAttributeFloat("loopdelay", 0.0f);
-
- if (playingSheets != null)
- {
- foreach (SpriteSheet existingSheet in playingSheets)
- {
- existingSheet.Remove();
- }
- playingSheets = null;
- }
-
- playingSheets = preloadedSheets.Find(s => s.ContentName == contentId).Sheets;
-
- if (playingSheets == null) // No preloaded sheets found, create sheets
- {
- playingSheets = CreateSpriteSheets(contentPath, videoElement);
- }
-
- currentSheet = playingSheets[0];
-
- Point resolution = currentSheet.FrameSize;
-
- videoFrame.RectTransform.NonScaledSize = resolution + new Point(borderSize, borderSize);
- sheetView.RectTransform.NonScaledSize = resolution;
-
- title.Text = TextManager.Get(contentId);
- title.RectTransform.NonScaledSize = new Point(resolution.X, 30);
-
- callbackOnStop = callback;
-
- if (hasButton)
- {
- var okButton = new GUIButton(new RectTransform(new Point(160, 50), videoFrame.RectTransform, Anchor.BottomCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, -10) },
- TextManager.Get("OK"))
- {
- OnClicked = OKButtonClicked
- };
- }
-
- if (startPlayback) Play();
- }
-
- private SpriteSheet[] CreateSpriteSheets(string contentPath, XElement videoElement)
- {
- SpriteSheet[] sheets = null;
-
- try
- {
- List sheetElements = new List();
-
- foreach (var sheetElement in videoElement.Elements("Sheet"))
- {
- sheetElements.Add(sheetElement);
- }
-
- sheets = new SpriteSheet[sheetElements.Count];
-
- for (int i = 0; i < sheetElements.Count; i++)
- {
- sheets[i] = new SpriteSheet(sheetElements[i], contentPath, sheetElements[i].GetAttributeString("path", ""), sheetElements[i].GetAttributeInt("empty", 0));
- }
- }
- catch (Exception e)
- {
- DebugConsole.ThrowError("Error loading sprite sheet content " + contentPath + "!", e);
- }
-
- return sheets;
- }
-
- private void UpdateSheetView(float deltaTime, GUICustomComponent viewContainer)
- {
- if (!isPlaying) return;
- if (loopTimer > 0.0f)
- {
- loopTimer -= deltaTime;
-
- if (loopTimer <= 0.0f)
- {
- currentSheetIndex = 0;
- currentFrameIndex = 0;
- currentSheet = playingSheets[currentSheetIndex];
- }
- else
- {
- return;
- }
- }
-
- totalElapsed += deltaTime;
- if (totalElapsed > animationSpeed)
- {
- totalElapsed -= animationSpeed;
- currentFrameIndex++;
-
- if (currentFrameIndex > currentSheet.FrameCount - 1)
- {
- currentSheetIndex++;
-
- if (currentSheetIndex > playingSheets.Length - 1)
- {
- if (loopDelay > 0.0f)
- {
- loopTimer = loopDelay;
- return;
- }
-
- currentSheetIndex = 0;
- }
-
- currentFrameIndex = 0;
- currentSheet = playingSheets[currentSheetIndex];
- }
- }
- }
-
- private void DrawSheetView(SpriteBatch spriteBatch, Rectangle rect)
- {
- if (!isPlaying) return;
- currentSheet.Draw(spriteBatch, currentFrameIndex, rect.Center.ToVector2(), Color.White, currentSheet.Origin, 0f, Vector2.One);
- }
-
- public void Remove()
- {
- if (playingSheets != null)
- {
- foreach (SpriteSheet existingSheet in playingSheets)
- {
- existingSheet.Remove();
- }
- playingSheets = null;
- }
-
- RemoveAllPreloaded();
- }
- }
-}
diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs
index ea04b257e..92e524f18 100644
--- a/Barotrauma/BarotraumaClient/Source/GameMain.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs
@@ -30,6 +30,8 @@ namespace Barotrauma
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
+ public static string[] ConsoleArguments;
+
public static GameScreen GameScreen;
public static MainMenuScreen MainMenuScreen;
public static LobbyScreen LobbyScreen;
@@ -116,7 +118,7 @@ namespace Barotrauma
get;
private set;
}
-
+
public static WindowMode WindowMode
{
get;
@@ -159,7 +161,7 @@ namespace Barotrauma
get { return loadingScreenOpen; }
}
- public GameMain()
+ public GameMain(string[] args)
{
Content.RootDirectory = "Content";
@@ -171,6 +173,8 @@ namespace Barotrauma
Config = new GameSettings();
+ ConsoleArguments = args;
+
GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);
PerformanceCounter = new PerformanceCounter();
@@ -294,7 +298,7 @@ namespace Barotrauma
loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "Load", canLoadInSeparateThread);
}
-
+
private void InitUserStats()
{
if (GameSettings.ShowUserStatisticsPrompt)
@@ -356,6 +360,11 @@ namespace Barotrauma
SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume);
SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume * 20.0f);
+
+ if (ConsoleArguments.Contains("skipintro")) {
+ Config.EnableSplashScreen = false;
+ }
+
if (Config.EnableSplashScreen)
{
var pendingSplashScreens = TitleScreen.PendingSplashScreens;
@@ -403,7 +412,7 @@ namespace Barotrauma
InitUserStats();
yield return CoroutineStatus.Running;
-
+
LightManager = new Lights.LightManager(base.GraphicsDevice, Content);
TitleScreen.LoadState = 1.0f;
@@ -664,7 +673,7 @@ namespace Barotrauma
GUI.KeyboardDispatcher.Subscriber = null;
}
//if a verification prompt (are you sure you want to x) is open, close it
- else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
+ else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
{
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
@@ -826,8 +835,8 @@ namespace Barotrauma
}
};
}
-
- msgBox.InnerFrame.RectTransform.MinSize = new Point(0,
+
+ msgBox.InnerFrame.RectTransform.MinSize = new Point(0,
msgBox.InnerFrame.Rect.Height + linkHolder.Rect.Height + msgBox.Content.AbsoluteSpacing * 2 + 10);
Config.EditorDisclaimerShown = true;
Config.SaveNewPlayerConfig();
@@ -878,6 +887,7 @@ namespace Barotrauma
if (NetworkMember != null) NetworkMember.Disconnect();
SteamManager.ShutDown();
if (GameSettings.SendUserStatistics) GameAnalytics.OnQuit();
+ if (GameSettings.SaveDebugConsoleLogs) DebugConsole.SaveLogs();
base.OnExiting(sender, args);
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs
index a95140454..647871bfa 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs
@@ -941,7 +941,7 @@ namespace Barotrauma
else
{
orderTargetFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f + order.Options.Length * 0.1f, 0.18f), GUI.Canvas)
- { AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) },
+ { AbsoluteOffset = new Point((int)(200 * GUI.Scale), orderButton.Rect.Bottom) },
isHorizontal: true, childAnchor: Anchor.BottomLeft)
{
UserData = character,
@@ -970,6 +970,12 @@ namespace Barotrauma
return true;
}
};
+ new GUIFrame(new RectTransform(Vector2.One * 1.5f, optionButton.RectTransform, Anchor.Center), style: "OuterGlow")
+ {
+ Color = Color.Black,
+ HoverColor = Color.CadetBlue,
+ PressedColor = Color.Black
+ }.RectTransform.SetAsFirstChild();
OrderOptionButtons.Add(optionButton);
@@ -1238,7 +1244,10 @@ namespace Barotrauma
}
hoverArea.Inflate(100, 100);
- if (!hoverArea.Contains(PlayerInput.MousePosition)) orderTargetFrame = null;
+ if (!hoverArea.Contains(PlayerInput.MousePosition) || PlayerInput.RightButtonClicked())
+ {
+ orderTargetFrame = null;
+ }
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs
index 0bb370465..d098cf3db 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/SinglePlayerCampaign.cs
@@ -256,6 +256,18 @@ namespace Barotrauma
{
if (c.Info == null || c.Inventory == null) { continue; }
var inventoryElement = new XElement("inventory");
+
+ // Recharge headset batteries
+ var headset = c.Inventory.FindItemByIdentifier("headset");
+ if (headset != null)
+ {
+ var battery = headset.OwnInventory.FindItemByTag("loadable");
+ if (battery != null)
+ {
+ battery.Condition = battery.MaxCondition;
+ }
+ }
+
c.SaveInventory(c.Inventory, inventoryElement);
c.Info.InventoryData = inventoryElement;
c.Inventory?.DeleteAllItems();
@@ -407,7 +419,8 @@ namespace Barotrauma
public override void Save(XElement element)
{
XElement modeElement = new XElement("SinglePlayerCampaign",
- new XAttribute("money", Money),
+ // Refunds the money when save & quitting from the map if there are items selected in the store
+ new XAttribute("money", Money + (CargoManager != null ? CargoManager.GetTotalItemCost() : 0)),
new XAttribute("cheatsenabled", CheatsEnabled));
CrewManager.Save(modeElement);
Map.Save(modeElement);
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs b/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs
index ffcc67311..823e0c6dc 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/RoundSummary.cs
@@ -42,8 +42,14 @@ namespace Barotrauma
RelativeSpacing = 0.03f
};
- GUIListBox infoTextBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.7f), paddedFrame.RectTransform));
-
+ GUIListBox infoTextBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.7f), paddedFrame.RectTransform))
+ {
+ Spacing = (int)(5 * GUI.Scale)
+ };
+
+ //spacing
+ new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), infoTextBox.Content.RectTransform), style: null);
+
string summaryText = TextManager.GetWithVariables(gameOver ? "RoundSummaryGameOver" :
(progress ? "RoundSummaryProgress" : "RoundSummaryReturn"), new string[2] { "[sub]", "[location]" },
new string[2] { Submarine.MainSub.Name, progress ? GameMain.GameSession.EndLocation.Name : GameMain.GameSession.StartLocation.Name });
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs
index cb8889292..dc704f775 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Deconstructor.cs
@@ -19,6 +19,8 @@ namespace Barotrauma.Items.Components
private GUIComponent inSufficientPowerWarning;
+ private bool pendingState;
+
partial void InitProjSpecific(XElement element)
{
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
@@ -73,32 +75,34 @@ namespace Barotrauma.Items.Components
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
{
- inSufficientPowerWarning.Visible = powerConsumption > 0 && voltage < minVoltage;
- //activateButton.Enabled = !inSufficientPowerWarning.Visible;
+ inSufficientPowerWarning.Visible = CurrPowerConsumption > 0 && !hasPower;
}
private bool ToggleActive(GUIButton button, object obj)
{
- SetActive(!IsActive, Character.Controlled);
-
- currPowerConsumption = IsActive ? powerConsumption : 0.0f;
-
if (GameMain.Client != null)
{
+ pendingState = !IsActive;
item.CreateClientEvent(this);
}
+ else
+ {
+ SetActive(!IsActive, Character.Controlled);
+ currPowerConsumption = IsActive ? powerConsumption : 0.0f;
+ }
return true;
}
public void ClientWrite(NetBuffer msg, object[] extraData = null)
{
- msg.Write(IsActive);
+ msg.Write(pendingState);
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
SetActive(msg.ReadBoolean());
+ progressTimer = msg.ReadSingle();
}
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs
index 9b6cf355e..984885460 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Fabricator.cs
@@ -34,6 +34,8 @@ namespace Barotrauma.Items.Components
private GUIComponent inSufficientPowerWarning;
+ private FabricationRecipe pendingFabricatedItem;
+
private Pair tooltip;
partial void InitProjSpecific()
@@ -403,7 +405,7 @@ namespace Barotrauma.Items.Components
}
}
}
-
+
private bool StartButtonClicked(GUIButton button, object obj)
{
if (selectedItem == null) { return false; }
@@ -412,19 +414,22 @@ namespace Barotrauma.Items.Components
outputInventoryHolder.Flash(Color.Red);
return false;
}
-
- if (fabricatedItem == null)
+
+ if (GameMain.Client != null)
{
- StartFabricating(selectedItem, Character.Controlled);
+ pendingFabricatedItem = fabricatedItem != null ? null : selectedItem;
+ item.CreateClientEvent(this);
}
else
{
- CancelFabricating(Character.Controlled);
- }
-
- if (GameMain.Client != null)
- {
- item.CreateClientEvent(this);
+ if (fabricatedItem == null)
+ {
+ StartFabricating(selectedItem, Character.Controlled);
+ }
+ else
+ {
+ CancelFabricating(Character.Controlled);
+ }
}
return true;
@@ -433,7 +438,7 @@ namespace Barotrauma.Items.Components
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
{
activateButton.Enabled = false;
- inSufficientPowerWarning.Visible = powerConsumption > 0 && voltage < minVoltage;
+ inSufficientPowerWarning.Visible = currPowerConsumption > 0 && !hasPower;
var availableIngredients = GetAvailableIngredients();
if (character != null)
@@ -457,7 +462,7 @@ namespace Barotrauma.Items.Components
public void ClientWrite(NetBuffer msg, object[] extraData = null)
{
- int itemIndex = fabricatedItem == null ? -1 : fabricationRecipes.IndexOf(fabricatedItem);
+ int itemIndex = pendingFabricatedItem == null ? -1 : fabricationRecipes.IndexOf(pendingFabricatedItem);
msg.WriteRangedInteger(-1, fabricationRecipes.Count - 1, itemIndex);
}
@@ -474,8 +479,8 @@ namespace Barotrauma.Items.Components
else
{
//if already fabricating the selected item, return
- if (fabricatedItem != null && fabricationRecipes.IndexOf(fabricatedItem) == itemIndex) return;
- if (itemIndex < 0 || itemIndex >= fabricationRecipes.Count) return;
+ if (fabricatedItem != null && fabricationRecipes.IndexOf(fabricatedItem) == itemIndex) { return; }
+ if (itemIndex < 0 || itemIndex >= fabricationRecipes.Count) { return; }
SelectItem(user, fabricationRecipes[itemIndex]);
StartFabricating(fabricationRecipes[itemIndex], user);
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs
index 0e058bbd9..d1f6f9ad4 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/MiniMap.cs
@@ -17,10 +17,14 @@ namespace Barotrauma.Items.Components
private GUITextBlock hullNameText, hullBreachText, hullAirQualityText, hullWaterText;
+ private string noPowerTip = "";
+
private List displayedSubs = new List();
partial void InitProjSpecific(XElement element)
{
+ noPowerTip = TextManager.Get("SteeringNoPowerTip");
+
GuiFrame.RectTransform.RelativeOffset = new Vector2(0.4f, 0.0f);
new GUICustomComponent(new RectTransform(new Vector2(0.9f, 0.85f), GuiFrame.RectTransform, Anchor.Center),
DrawHUDBack, null);
@@ -105,6 +109,16 @@ namespace Barotrauma.Items.Components
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
{
+ if (voltage < minVoltage)
+ {
+ Vector2 textSize = GUI.Font.MeasureString(noPowerTip);
+ Vector2 textPos = GuiFrame.Rect.Center.ToVector2();
+
+ GUI.DrawString(spriteBatch, textPos - textSize / 2, noPowerTip,
+ Color.Orange * (float)Math.Abs(Math.Sin(Timing.TotalTime)), Color.Black * 0.8f);
+ return;
+ }
+
foreach (GUIComponent child in submarineContainer.Children.First().Children)
{
if (child.UserData is Hull hull)
@@ -145,6 +159,11 @@ namespace Barotrauma.Items.Components
}
}
+ if (voltage < minVoltage)
+ {
+ return;
+ }
+
float scale = 1.0f;
HashSet subs = new HashSet();
foreach (Hull hull in Hull.hullList)
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs
index 840f47fb3..4b9fe65a0 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs
@@ -34,7 +34,8 @@ namespace Barotrauma.Items.Components
private GUITickBox directionalTickBox;
private GUIScrollBar directionalSlider;
- private GUIComponent activeControlsContainer;
+ private GUILayoutGroup activeControlsContainer;
+ private GUIFrame controlContainer;
private GUICustomComponent sonarView;
@@ -76,12 +77,11 @@ namespace Barotrauma.Items.Components
{
sonarBlips = new List();
- int viewSize = (int)Math.Min(GuiFrame.Rect.Width - 150, GuiFrame.Rect.Height * 0.9f);
- sonarView = new GUICustomComponent(new RectTransform(new Point(viewSize), GuiFrame.RectTransform, Anchor.CenterLeft),
+ sonarView = new GUICustomComponent(new RectTransform(Point.Zero, GuiFrame.RectTransform, Anchor.CenterLeft),
(spriteBatch, guiCustomComponent) => { DrawSonar(spriteBatch, guiCustomComponent.Rect); }, null);
- var controlContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), GuiFrame.RectTransform, Anchor.TopLeft)
- { MinSize = new Point(150, 0), AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0) }, "SonarFrame");
+ controlContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), GuiFrame.RectTransform, Anchor.TopLeft)
+ { MinSize = new Point(150, 0) }, "SonarFrame");
controlContainer.RectTransform.SetAsFirstChild();
@@ -200,6 +200,18 @@ namespace Barotrauma.Items.Components
break;
}
}
+
+ SetUILayout();
+
+ GameMain.Instance.OnResolutionChanged += SetUILayout;
+ GameMain.Config.OnHUDScaleChanged += SetUILayout;
+ }
+
+ private void SetUILayout()
+ {
+ int viewSize = (int)Math.Min(GuiFrame.Rect.Width - 150, GuiFrame.Rect.Height * 0.9f);
+ sonarView.RectTransform.NonScaledSize = new Point(viewSize);
+ controlContainer.RectTransform.AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0);
}
public override void OnItemLoaded()
@@ -612,6 +624,16 @@ namespace Barotrauma.Items.Components
{
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
+ //don't show the docking ports of the opposing team on the sonar
+ if (item.Submarine != null && dockingPort.Item.Submarine != null)
+ {
+ if ((dockingPort.Item.Submarine.TeamID == Character.TeamType.Team1 && item.Submarine.TeamID == Character.TeamType.Team2) ||
+ (dockingPort.Item.Submarine.TeamID == Character.TeamType.Team2 && item.Submarine.TeamID == Character.TeamType.Team1))
+ {
+ continue;
+ }
+ }
+
Vector2 offset = (dockingPort.Item.WorldPosition - transducerCenter) * scale;
offset.Y = -offset.Y;
if (offset.LengthSquared() > DisplayRadius * DisplayRadius) { continue; }
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Steering.cs
index a6fc8d8e2..0f57fa4da 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Steering.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Steering.cs
@@ -27,7 +27,7 @@ namespace Barotrauma.Items.Components
};
private GUITickBox maintainPosTickBox, levelEndTickBox, levelStartTickBox;
- private GUIComponent statusContainer, dockingContainer;
+ private GUIComponent statusContainer, dockingContainer, controlContainer;
private bool dockingNetworkMessagePending;
@@ -86,9 +86,8 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific(XElement element)
{
- int viewSize = (int)Math.Min(GuiFrame.Rect.Width - 150, GuiFrame.Rect.Height * 0.9f);
- var controlContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), GuiFrame.RectTransform, Anchor.CenterLeft)
- { MinSize = new Point(150, 0), AbsoluteOffset = new Point((int)(viewSize * 0.99f), (int)(viewSize * 0.05f)) }, "SonarFrame");
+ controlContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), GuiFrame.RectTransform, Anchor.CenterLeft)
+ { MinSize = new Point(150, 0) }, "SonarFrame");
var paddedControlContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), controlContainer.RectTransform, Anchor.Center))
{
RelativeSpacing = 0.03f,
@@ -96,7 +95,7 @@ namespace Barotrauma.Items.Components
};
statusContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GuiFrame.RectTransform, Anchor.BottomLeft)
- { MinSize = new Point(150, 0), AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0) }, "SonarFrame");
+ { MinSize = new Point(150, 0) }, "SonarFrame");
var paddedStatusContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), statusContainer.RectTransform, Anchor.Center))
{
RelativeSpacing = 0.03f,
@@ -295,12 +294,12 @@ namespace Barotrauma.Items.Components
autoPilotLevelEndTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.EndLocation == null ? "End" : GameMain.GameSession.EndLocation.Name);
- steerArea = new GUICustomComponent(new RectTransform(new Point(viewSize), GuiFrame.RectTransform, Anchor.CenterLeft),
+ steerArea = new GUICustomComponent(new RectTransform(Point.Zero, GuiFrame.RectTransform, Anchor.CenterLeft),
(spriteBatch, guiCustomComponent) => { DrawHUD(spriteBatch, guiCustomComponent.Rect); }, null);
//docking interface ----------------------------------------------------
dockingContainer = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GuiFrame.RectTransform, Anchor.BottomLeft)
- { MinSize = new Point(150, 0), AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0) }, style: null);
+ { MinSize = new Point(150, 0) }, style: null);
var paddedDockingContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), dockingContainer.RectTransform, Anchor.Center), style: null);
//TODO: add new texts for these ("Dock" & "Undock")
@@ -364,6 +363,21 @@ namespace Barotrauma.Items.Components
break;
}
}
+
+ SetUILayout();
+
+ GameMain.Instance.OnResolutionChanged += SetUILayout;
+ GameMain.Config.OnHUDScaleChanged += SetUILayout;
+ }
+
+ private void SetUILayout()
+ {
+ int viewSize = (int)Math.Min(GuiFrame.Rect.Width - 150, GuiFrame.Rect.Height * 0.9f);
+
+ controlContainer.RectTransform.AbsoluteOffset = new Point((int)(viewSize * 0.99f), (int)(viewSize * 0.05f));
+ statusContainer.RectTransform.AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0);
+ steerArea.RectTransform.NonScaledSize = new Point(viewSize);
+ dockingContainer.RectTransform.AbsoluteOffset = new Point((int)(viewSize * 0.9f), 0);
}
private void FindConnectedDockingPort()
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Connection.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Connection.cs
index 294f6214b..ba5580dc7 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Connection.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Signal/Connection.cs
@@ -41,8 +41,9 @@ namespace Barotrauma.Items.Components
}
Wire equippedWire = null;
-
- if (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen)
+
+ bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring;
+ if (allowRewiring && (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
{
//if the Character using the panel has a wire item equipped
//and the wire hasn't been connected yet, draw it on the panel
@@ -278,7 +279,8 @@ namespace Barotrauma.Items.Components
{
ConnectionPanel.HighlightedWire = wire;
- if (!wire.Locked && (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
+ bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring;
+ if (allowRewiring && !wire.Locked && (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
{
//start dragging the wire
if (PlayerInput.LeftButtonHeld()) draggingConnected = wire;
diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs
index f6e4cb04a..ba6bc9a40 100644
--- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs
+++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs
@@ -181,7 +181,7 @@ namespace Barotrauma
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
- if (!Visible || (!editing && hiddenInGame)) return;
+ if (!Visible || (!editing && HiddenInGame)) return;
if (editing && !ShowItems) return;
Color color = IsHighlighted && !GUI.DisableItemHighlights && Screen.Selected != GameMain.GameScreen ? Color.Orange : GetSpriteColor();
@@ -451,7 +451,7 @@ namespace Barotrauma
public override void UpdateEditing(Camera cam)
{
- if (editingHUD == null || editingHUD.UserData == null)
+ if (editingHUD == null || editingHUD.UserData as Item != this)
{
editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
}
diff --git a/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs b/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs
index 215e2db4d..f5da6ece8 100644
--- a/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs
+++ b/Barotrauma/BarotraumaClient/Source/Map/MapEntity.cs
@@ -132,96 +132,97 @@ namespace Barotrauma
selectedList.Clear();
return;
}
-
- if (PlayerInput.KeyDown(Keys.Delete))
+ if (GUI.KeyboardDispatcher.Subscriber == null)
{
- selectedList.ForEach(e => e.Remove());
- selectedList.Clear();
- }
-
- if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
- {
- if (PlayerInput.KeyHit(Keys.C))
+ if (PlayerInput.KeyDown(Keys.Delete))
{
- CopyEntities(selectedList);
- }
- else if (PlayerInput.KeyHit(Keys.X))
- {
- CopyEntities(selectedList);
-
selectedList.ForEach(e => e.Remove());
selectedList.Clear();
}
- else if (copiedList.Count > 0 && PlayerInput.KeyHit(Keys.V))
+
+ if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
{
- List prevEntities = new List(mapEntityList);
- Clone(copiedList);
-
- var clones = mapEntityList.Except(prevEntities).ToList();
-
- Vector2 center = Vector2.Zero;
- clones.ForEach(c => center += c.WorldPosition);
- center = Submarine.VectorToWorldGrid(center / clones.Count);
-
- Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);
-
- selectedList = new List(clones);
- foreach (MapEntity clone in selectedList)
+ if (PlayerInput.KeyHit(Keys.C))
{
- clone.Move(moveAmount);
- clone.Submarine = Submarine.MainSub;
+ CopyEntities(selectedList);
}
- }
- else if (PlayerInput.KeyHit(Keys.G))
- {
- if (selectedList.Any())
+ else if (PlayerInput.KeyHit(Keys.X))
{
- if (SelectionGroups.ContainsKey(selectedList.Last()))
+ CopyEntities(selectedList);
+
+ selectedList.ForEach(e => e.Remove());
+ selectedList.Clear();
+ }
+ else if (copiedList.Count > 0 && PlayerInput.KeyHit(Keys.V))
+ {
+ List prevEntities = new List(mapEntityList);
+ Clone(copiedList);
+
+ var clones = mapEntityList.Except(prevEntities).ToList();
+
+ Vector2 center = Vector2.Zero;
+ clones.ForEach(c => center += c.WorldPosition);
+ center = Submarine.VectorToWorldGrid(center / clones.Count);
+
+ Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);
+
+ selectedList = new List(clones);
+ foreach (MapEntity clone in selectedList)
{
- // Ungroup all selected
- selectedList.ForEach(e => SelectionGroups.Remove(e));
+ clone.Move(moveAmount);
+ clone.Submarine = Submarine.MainSub;
}
- else
+ }
+ else if (PlayerInput.KeyHit(Keys.G))
+ {
+ if (selectedList.Any())
{
- foreach (var entity in selectedList)
+ if (SelectionGroups.ContainsKey(selectedList.Last()))
{
- // Remove the old group, if any
- SelectionGroups.Remove(entity);
- // Create a group that can be accessed with any member
- SelectionGroups.Add(entity, selectedList);
+ // Ungroup all selected
+ selectedList.ForEach(e => SelectionGroups.Remove(e));
+ }
+ else
+ {
+ foreach (var entity in selectedList)
+ {
+ // Remove the old group, if any
+ SelectionGroups.Remove(entity);
+ // Create a group that can be accessed with any member
+ SelectionGroups.Add(entity, selectedList);
+ }
+ }
+ }
+ }
+ else if (PlayerInput.KeyHit(Keys.Z))
+ {
+ SetPreviousRects(e => e.rectMemento.Undo());
+ }
+ else if (PlayerInput.KeyHit(Keys.R))
+ {
+ SetPreviousRects(e => e.rectMemento.Redo());
+ }
+
+ void SetPreviousRects(Func memoryMethod)
+ {
+ foreach (var e in SelectedList)
+ {
+ if (e.rectMemento != null)
+ {
+ Point diff = memoryMethod(e).Location - e.Rect.Location;
+ // We have to call the move method, because there's a lot more than just storing the rect (in some cases)
+ // We also have to reassign the rect, because the move method does not set the width and height. They might have changed too.
+ // The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures.
+ e.Move(diff.ToVector2());
+ e.Rect = e.rectMemento.Current;
}
}
}
}
- else if (PlayerInput.KeyHit(Keys.Z))
- {
- SetPreviousRects(e => e.rectMemento.Undo());
- }
- else if (PlayerInput.KeyHit(Keys.R))
- {
- SetPreviousRects(e => e.rectMemento.Redo());
- }
- void SetPreviousRects(Func memoryMethod)
- {
- foreach (var e in SelectedList)
- {
- if (e.rectMemento != null)
- {
- Point diff = memoryMethod(e).Location - e.Rect.Location;
- // We have to call the move method, because there's a lot more than just storing the rect (in some cases)
- // We also have to reassign the rect, because the move method does not set the width and height. They might have changed too.
- // The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures.
- e.Move(diff.ToVector2());
- e.Rect = e.rectMemento.Current;
- }
- }
- }
- }
+ }
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
-
MapEntity highLightedEntity = null;
-
if (startMovingPos == Vector2.Zero)
{
List highlightedEntities = new List();
@@ -282,16 +283,19 @@ namespace Barotrauma
if (highLightedEntity != null) highLightedEntity.isHighlighted = true;
}
- Vector2 nudgeAmount = Vector2.Zero;
- if (PlayerInput.KeyHit(Keys.Up)) nudgeAmount.Y = 1f;
- if (PlayerInput.KeyHit(Keys.Down)) nudgeAmount.Y = -1f;
- if (PlayerInput.KeyHit(Keys.Left)) nudgeAmount.X = -1f;
- if (PlayerInput.KeyHit(Keys.Right)) nudgeAmount.X = 1f;
- if (nudgeAmount != Vector2.Zero)
+ if (GUI.KeyboardDispatcher.Subscriber == null)
{
- foreach (MapEntity entityToNudge in selectedList)
+ Vector2 nudgeAmount = Vector2.Zero;
+ if (PlayerInput.KeyHit(Keys.Up)) nudgeAmount.Y = 1f;
+ if (PlayerInput.KeyHit(Keys.Down)) nudgeAmount.Y = -1f;
+ if (PlayerInput.KeyHit(Keys.Left)) nudgeAmount.X = -1f;
+ if (PlayerInput.KeyHit(Keys.Right)) nudgeAmount.X = 1f;
+ if (nudgeAmount != Vector2.Zero)
{
- entityToNudge.Move(nudgeAmount);
+ foreach (MapEntity entityToNudge in selectedList)
+ {
+ entityToNudge.Move(nudgeAmount);
+ }
}
}
@@ -619,7 +623,7 @@ namespace Barotrauma
if (selectedList.Count == 0) return;
foreach (var e in selectedList)
{
- if (e is Gap) { continue; }
+ if (e is Gap gap && gap.ConnectedDoor != null) { continue; }
FilteredSelectedList.Add(e);
}
var first = FilteredSelectedList.FirstOrDefault();
diff --git a/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs b/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs
index 27c059ccf..c14813c0b 100644
--- a/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs
+++ b/Barotrauma/BarotraumaClient/Source/Map/WayPoint.cs
@@ -18,11 +18,16 @@ namespace Barotrauma
return Screen.Selected == GameMain.SubEditorScreen || GameMain.DebugDraw;
}
+ public override bool SelectableInEditor
+ {
+ get { return !IsHidden(); }
+ }
+
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
- if (!editing && !GameMain.DebugDraw) return;
+ if (!editing && !GameMain.DebugDraw) { return; }
- if (IsHidden()) return;
+ if (IsHidden()) { return; }
//Rectangle drawRect =
// Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
index 482ee45a0..91366725a 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs
@@ -1093,6 +1093,7 @@ namespace Barotrauma.Networking
bool loadSecondSub = inc.ReadBoolean();
bool disguisesAllowed = inc.ReadBoolean();
+ bool rewiringAllowed = inc.ReadBoolean();
bool isTraitor = inc.ReadBoolean();
string traitorTargetName = isTraitor ? inc.ReadString() : null;
@@ -1114,6 +1115,7 @@ namespace Barotrauma.Networking
GameMain.LightManager.LosMode = (LosMode)losMode;
serverSettings.AllowDisguises = disguisesAllowed;
+ serverSettings.AllowRewiring = rewiringAllowed;
serverSettings.AllowRagdollButton = allowRagdollButton;
if (campaign == null)
@@ -1706,6 +1708,8 @@ namespace Barotrauma.Networking
case FileTransferType.Submarine:
new GUIMessageBox(TextManager.Get("ServerDownloadFinished"), TextManager.GetWithVariable("FileDownloadedNotification", "[filename]", transfer.FileName));
var newSub = new Submarine(transfer.FilePath);
+ if (newSub.IsFileCorrupted) { return; }
+
var existingSubs = Submarine.SavedSubmarines.Where(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash).ToList();
foreach (Submarine existingSub in existingSubs)
{
@@ -2494,7 +2498,7 @@ namespace Barotrauma.Networking
}
else
{
- BanPlayer(clientName, banReasonBox.Text, ban);
+ BanPlayer(clientName, banReasonBox.Text, range: rangeBan);
}
}
else
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs b/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs
index 0223c9c69..ec1f695e5 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/ServerInfo.cs
@@ -60,54 +60,35 @@ namespace Barotrauma.Networking
return contentPackageHashes.SetEquals(myContentPackageHashes);
}
- public void CreatePreviewWindow(GUIListBox listBox)
+ public void CreatePreviewWindow(GUIFrame frame)
{
- listBox.ClearChildren();
+ frame.ClearChildren();
- if (listBox == null) return;
+ if (frame == null) return;
- var previewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), listBox.Content.RectTransform, Anchor.Center))
+ var previewContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1.0f), frame.RectTransform, Anchor.Center))
{
Stretch = true
};
- var titleHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), previewContainer.RectTransform))
+ var columnContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), previewContainer.RectTransform))
{
- IsHorizontal = true,
Stretch = true
};
- var title = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), titleHolder.RectTransform), ServerName, font: GUI.LargeFont, wrap: true);
+ float elementHeight = 0.075f;
+
+ var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnContainer.RectTransform), ServerName, font: GUI.LargeFont);
title.Text = ToolBox.LimitString(title.Text, title.Font, title.Rect.Width);
- new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), titleHolder.RectTransform),
- TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion),
- textAlignment: Alignment.Right);
-
- var columnContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), previewContainer.RectTransform), isHorizontal: true)
- {
- Stretch = true,
- RelativeSpacing = 0.005f
- };
-
- var columnLeft = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), columnContainer.RectTransform))
- {
- RelativeSpacing = 0.02f,
- Stretch = true
- };
- var columnRight = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), columnContainer.RectTransform))
- {
- RelativeSpacing = 0.02f,
- Stretch = true
- };
-
- float elementHeight = 0.1f;
+ new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnContainer.RectTransform),
+ TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion));
// left column -----------------------------------------------------------------------------
//new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnLeft.RectTransform), IP + ":" + Port);
- var serverMsg = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), columnLeft.RectTransform)) { ScrollBarVisible = true };
+ var serverMsg = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.5f), columnContainer.RectTransform)) { ScrollBarVisible = true };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverMsg.Content.RectTransform), ServerMessage, wrap: true) { CanBeFocused = false };
// right column -----------------------------------------------------------------------------
@@ -122,20 +103,22 @@ namespace Barotrauma.Networking
CanBeFocused = false
};*/
- var gameMode = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("GameMode"));
- new GUITextBlock(new RectTransform(Vector2.One, gameMode.RectTransform), TextManager.Get(string.IsNullOrEmpty(GameMode) ? "Unknown" : GameMode), textAlignment: Alignment.Right);
+ var gameMode = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("GameMode"));
+ new GUITextBlock(new RectTransform(Vector2.One, gameMode.RectTransform),
+ TextManager.Get(string.IsNullOrEmpty(GameMode) ? "Unknown" : "GameMode." + GameMode, returnNull: true) ?? GameMode,
+ textAlignment: Alignment.Right);
+
+ var traitors = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("Traitors"));
- var traitors = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("Traitors"));
new GUITextBlock(new RectTransform(Vector2.One, traitors.RectTransform), TextManager.Get(!TraitorsEnabled.HasValue ? "Unknown" : TraitorsEnabled.Value.ToString()), textAlignment: Alignment.Right);
-
- var subSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListSubSelection"));
+ var subSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListSubSelection"));
new GUITextBlock(new RectTransform(Vector2.One, subSelection.RectTransform), TextManager.Get(!SubSelectionMode.HasValue ? "Unknown" : SubSelectionMode.Value.ToString()), textAlignment: Alignment.Right);
- var modeSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListModeSelection"));
+ var modeSelection = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListModeSelection"));
new GUITextBlock(new RectTransform(Vector2.One, modeSelection.RectTransform), TextManager.Get(!ModeSelectionMode.HasValue ? "Unknown" : ModeSelectionMode.Value.ToString()), textAlignment: Alignment.Right);
- var allowSpectating = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListAllowSpectating"))
+ var allowSpectating = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListAllowSpectating"))
{
CanBeFocused = false
};
@@ -144,7 +127,7 @@ namespace Barotrauma.Networking
else
allowSpectating.Selected = AllowSpectating.Value;
- var allowRespawn = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnRight.RectTransform), TextManager.Get("ServerSettingsAllowRespawning"))
+ var allowRespawn = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerSettingsAllowRespawning"))
{
CanBeFocused = false
};
@@ -153,7 +136,7 @@ namespace Barotrauma.Networking
else
allowRespawn.Selected = AllowRespawn.Value;
- var voipEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), columnRight.RectTransform), TextManager.Get("serversettingsvoicechatenabled"))
+ var voipEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), columnContainer.RectTransform), TextManager.Get("serversettingsvoicechatenabled"))
{
CanBeFocused = false
};
@@ -162,7 +145,7 @@ namespace Barotrauma.Networking
else
voipEnabledTickBox.Selected = VoipEnabled.Value;
- var usingWhiteList = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnRight.RectTransform), TextManager.Get("ServerListUsingWhitelist"))
+ var usingWhiteList = new GUITickBox(new RectTransform(new Vector2(1, elementHeight), columnContainer.RectTransform), TextManager.Get("ServerListUsingWhitelist"))
{
CanBeFocused = false
};
@@ -171,10 +154,16 @@ namespace Barotrauma.Networking
else
usingWhiteList.Selected = UsingWhiteList.Value;
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnRight.RectTransform),
+
+ columnContainer.RectTransform.SizeChanged += () =>
+ {
+ GUITextBlock.AutoScaleAndNormalize(allowSpectating.TextBlock, allowRespawn.TextBlock, voipEnabledTickBox.TextBlock, usingWhiteList.TextBlock);
+ };
+
+ new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), columnContainer.RectTransform),
TextManager.Get("ServerListContentPackages"));
- var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), columnRight.RectTransform));
+ var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), columnContainer.RectTransform)) { ScrollBarVisible = true };
if (ContentPackageNames.Count == 0)
{
new GUITextBlock(new RectTransform(Vector2.One, contentPackageList.Content.RectTransform), TextManager.Get("Unknown"), textAlignment: Alignment.Center)
@@ -223,7 +212,7 @@ namespace Barotrauma.Networking
}
if (availableWorkshopUrls.Count > 0)
{
- var workshopBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.15f), columnLeft.RectTransform), TextManager.Get("ServerListSubscribeMissingPackages"))
+ var workshopBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), columnContainer.RectTransform), TextManager.Get("ServerListSubscribeMissingPackages"))
{
ToolTip = TextManager.Get(SteamManager.IsInitialized ? "ServerListSubscribeMissingPackagesTooltip" : "ServerListSubscribeMissingPackagesTooltipNoSteam"),
Enabled = SteamManager.IsInitialized,
@@ -240,11 +229,7 @@ namespace Barotrauma.Networking
// -----------------------------------------------------------------------------
- foreach (GUIComponent c in columnLeft.Children)
- {
- if (c is GUITextBlock textBlock) textBlock.Padding = Vector4.Zero;
- }
- foreach (GUIComponent c in columnRight.Children)
+ foreach (GUIComponent c in columnContainer.Children)
{
if (c is GUITextBlock textBlock) textBlock.Padding = Vector4.Zero;
}
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs
index ea5dfb19c..e505a5d24 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/SteamManager.cs
@@ -242,6 +242,10 @@ namespace Barotrauma.Steam
if (s.Rules.ContainsKey("gamestarted")) serverInfo.GameStarted = s.Rules["gamestarted"] == "True";
+ if (s.Rules.ContainsKey("gamemode"))
+ {
+ serverInfo.GameMode = s.Rules["gamemode"];
+ }
if (serverInfo.ContentPackageNames.Count != serverInfo.ContentPackageHashes.Count ||
serverInfo.ContentPackageHashes.Count != serverInfo.ContentPackageWorkshopUrls.Count)
{
@@ -596,7 +600,7 @@ namespace Barotrauma.Steam
}
else
{
- DebugConsole.ThrowError("Publishing workshop item " + item.Title + " failed. " + item.Error);
+ DebugConsole.NewMessage("Publishing workshop item " + item.Title + " failed. " + item.Error, Microsoft.Xna.Framework.Color.Red);
}
SaveUtil.ClearFolder(WorkshopItemStagingFolder);
diff --git a/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs b/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs
index f47145846..f0bcb18f2 100644
--- a/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs
+++ b/Barotrauma/BarotraumaClient/Source/Networking/Voip/VoipCapture.cs
@@ -73,15 +73,31 @@ namespace Barotrauma.Networking
if (captureDevice == IntPtr.Zero)
{
+ DebugConsole.NewMessage("Alc.CaptureOpenDevice attempt 1 failed: error code " + Alc.GetError(IntPtr.Zero).ToString(),Color.Orange);
+ //attempt using a smaller buffer size
+ captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 2);
+ }
+
+ if (captureDevice == IntPtr.Zero)
+ {
+ DebugConsole.NewMessage("Alc.CaptureOpenDevice attempt 2 failed: error code " + Alc.GetError(IntPtr.Zero).ToString(), Color.Orange);
+ //attempt using the default device
+ captureDevice = Alc.CaptureOpenDevice("", VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 2);
+ }
+
+ if (captureDevice == IntPtr.Zero)
+ {
+ string errorCode = Alc.GetError(IntPtr.Zero).ToString();
if (!GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "capturedevicenotfound"))
{
GUI.SettingsMenuOpen = false;
- new GUIMessageBox(TextManager.Get("Error"),
- TextManager.Get("VoipCaptureDeviceNotFound", returnNull: true) ?? "Could not start voice capture, suitable capture device not found.")
+ new GUIMessageBox(TextManager.Get("Error"),
+ (TextManager.Get("VoipCaptureDeviceNotFound", returnNull: true) ?? "Could not start voice capture, suitable capture device not found.") + " (" + errorCode + ")")
{
UserData = "capturedevicenotfound"
};
}
+ GameAnalyticsManager.AddErrorEventOnce("Alc.CaptureDeviceOpen(" + deviceName + ") failed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,"Error code: "+errorCode);
GameMain.Config.VoiceSetting = GameSettings.VoiceMode.Disabled;
Instance?.Dispose();
Instance = null;
diff --git a/Barotrauma/BarotraumaClient/Source/Program.cs b/Barotrauma/BarotraumaClient/Source/Program.cs
index 9c1a2d340..b64ef62d9 100644
--- a/Barotrauma/BarotraumaClient/Source/Program.cs
+++ b/Barotrauma/BarotraumaClient/Source/Program.cs
@@ -6,6 +6,7 @@ using System.Linq;
using System.Text;
using GameAnalyticsSDK.Net;
using Barotrauma.Steam;
+using System.Diagnostics;
#if WINDOWS
using System.Windows.Forms;
@@ -28,7 +29,7 @@ namespace Barotrauma
/// The main entry point for the application.
///
[STAThread]
- static void Main()
+ static void Main(string[] args)
{
SteamManager.Initialize();
GameMain game = null;
@@ -36,7 +37,7 @@ namespace Barotrauma
try
{
#endif
- game = new GameMain();
+ game = new GameMain(args);
#if !DEBUG
}
catch (Exception e)
@@ -151,11 +152,14 @@ namespace Barotrauma
return false;
}
- public static void CrashMessageBox(string message)
+ public static void CrashMessageBox(string message, string filePath)
{
#if WINDOWS
MessageBox.Show(message, "Oops! Barotrauma just crashed.", MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
+
+ // Open the crash log.
+ Process.Start(filePath);
}
static void CrashDump(GameMain game, string filePath, Exception exception)
@@ -278,14 +282,14 @@ namespace Barotrauma
if (GameSettings.SendUserStatistics)
{
- CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers.");
+ CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers.", filePath);
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
GameAnalytics.OnQuit();
}
else
{
CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game. The error was not sent to the developers because user statistics have been disabled, but" +
- " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/");
+ " if you'd like to help fix this bug, you may post it on Barotrauma's GitHub issue tracker: https://github.com/Regalis11/Barotrauma/issues/", filePath);
}
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs
index 36bda70df..e396b450d 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs
@@ -32,13 +32,15 @@ namespace Barotrauma
}
}
+ private bool ShowExtraRagdollControls => selectedLimbs.Any() && editLimbs || selectedJoints.Any() && editJoints;
+
private Character character;
private Vector2 spawnPosition;
private bool editAnimations;
private bool editLimbs;
private bool editJoints;
private bool editIK;
- private bool showRagdoll;
+ private bool editRagdoll;
private bool showParamsEditor;
private bool showSpritesheet;
private bool isFreezed;
@@ -50,15 +52,17 @@ namespace Barotrauma
private bool lockSpriteSize;
private bool recalculateCollider;
private bool copyJointSettings;
- private bool displayColliders;
+ private bool showColliders;
private bool displayWearables;
private bool displayBackgroundColor;
private bool ragdollResetRequiresForceLoading;
private bool animationResetRequiresForceLoading;
- private float cameraFollowSpeed = 20;
+ private bool jointCreationMode;
+ private bool useMouseOffset;
private bool isExtrudingJoint;
private bool isDrawingJoint;
+ private Limb closestSelectedLimb;
private Limb targetLimb;
private Vector2? anchor1Pos;
@@ -69,6 +73,7 @@ namespace Barotrauma
private int spriteSheetOffsetX;
private bool hideBodySheet;
private Color backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
+ private Vector2 cameraOffset;
private List selectedJoints = new List();
private List selectedLimbs = new List();
@@ -139,7 +144,7 @@ namespace Barotrauma
editLimbs = false;
editJoints = false;
editIK = false;
- showRagdoll = false;
+ editRagdoll = false;
showParamsEditor = false;
showSpritesheet = false;
isFreezed = false;
@@ -151,14 +156,21 @@ namespace Barotrauma
lockSpriteSize = false;
recalculateCollider = false;
copyJointSettings = false;
- displayColliders = false;
+ showColliders = false;
displayWearables = true;
displayBackgroundColor = false;
ragdollResetRequiresForceLoading = false;
animationResetRequiresForceLoading = false;
+ jointCreationMode = false;
isExtrudingJoint = false;
isDrawingJoint = false;
- Wizard.instance = null;
+ cameraOffset = Vector2.Zero;
+ targetLimb = null;
+ anchor1Pos = null;
+ useMouseOffset = false;
+ closestSelectedLimb = null;
+ allFiles = null;
+ Wizard.instance?.Reset();
}
private void Reset()
@@ -222,7 +234,13 @@ namespace Barotrauma
public override void AddToGUIUpdateList()
{
//base.AddToGUIUpdateList();
- rightPanel.AddToGUIUpdateList();
+
+ fileEditPanel.AddToGUIUpdateList();
+ modesPanel.AddToGUIUpdateList();
+ toolsPanel.AddToGUIUpdateList();
+ optionsPanel.AddToGUIUpdateList();
+ characterSelectionPanel.AddToGUIUpdateList();
+
Wizard.instance?.AddToGUIUpdateList();
if (displayBackgroundColor)
{
@@ -236,17 +254,25 @@ namespace Barotrauma
{
spriteSheetControls.AddToGUIUpdateList();
}
- if (editJoints)
+ if (editRagdoll)
{
ragdollControls.AddToGUIUpdateList();
}
+ if (editJoints)
+ {
+ jointControls.AddToGUIUpdateList();
+ }
if (editLimbs)
{
limbControls.AddToGUIUpdateList();
}
if (showParamsEditor)
{
- ParamsEditor.Instance.EditorBox.AddToGUIUpdateList();
+ ParamsEditor.Instance.EditorBox.Parent.AddToGUIUpdateList();
+ }
+ if (ShowExtraRagdollControls)
+ {
+ extraRagdollControls.AddToGUIUpdateList();
}
}
@@ -257,6 +283,18 @@ namespace Barotrauma
// Handle shortcut keys
if (GUI.KeyboardDispatcher.Subscriber == null && Wizard.instance == null)
{
+ if (PlayerInput.KeyHit(Keys.D1))
+ {
+ SetToggle(editLimbsToggle, true);
+ }
+ else if (PlayerInput.KeyHit(Keys.D2))
+ {
+ SetToggle(jointsToggle, true);
+ }
+ else if (PlayerInput.KeyHit(Keys.D3))
+ {
+ SetToggle(editAnimsToggle, true);
+ }
if (PlayerInput.KeyDown(Keys.LeftControl))
{
Character.DisableControls = true;
@@ -313,9 +351,12 @@ namespace Barotrauma
{
copyJointsToggle.Selected = !copyJointsToggle.Selected;
}
- if (PlayerInput.KeyHit(Keys.T) || PlayerInput.KeyHit(Keys.X))
+ if (character.IsHumanoid)
{
- animTestPoseToggle.Selected = !animTestPoseToggle.Selected;
+ if (PlayerInput.KeyHit(Keys.T) || PlayerInput.KeyHit(Keys.X))
+ {
+ animTestPoseToggle.Selected = !animTestPoseToggle.Selected;
+ }
}
if (PlayerInput.KeyHit(InputType.Run))
{
@@ -352,7 +393,7 @@ namespace Barotrauma
CurrentAnimation.CreateSnapshot();
}
}
- if (PlayerInput.KeyHit(Keys.E))
+ if (!PlayerInput.KeyDown(Keys.LeftControl) && PlayerInput.KeyHit(Keys.E))
{
bool isSwimming = character.AnimController.ForceSelectAnimationType == AnimationType.SwimFast || character.AnimController.ForceSelectAnimationType == AnimationType.SwimSlow;
if (isSwimming)
@@ -366,9 +407,9 @@ namespace Barotrauma
}
if (PlayerInput.KeyHit(Keys.F))
{
- freezeToggle.Selected = !freezeToggle.Selected;
+ SetToggle(freezeToggle, !freezeToggle.Selected);
}
- if (PlayerInput.RightButtonClicked())
+ if (PlayerInput.RightButtonClicked() || PlayerInput.KeyHit(Keys.Escape))
{
bool reset = false;
if (selectedLimbs.Any())
@@ -390,6 +431,8 @@ namespace Barotrauma
{
ResetParamsEditor();
}
+ jointCreationMode = false;
+ closestSelectedLimb = null;
}
if (PlayerInput.KeyHit(Keys.Delete))
{
@@ -397,15 +440,33 @@ namespace Barotrauma
}
if (editLimbs && PlayerInput.KeyDown(Keys.LeftControl))
{
- if (PlayerInput.KeyHit(Keys.C))
+ var selectedLimb = selectedLimbs.FirstOrDefault();
+ if (selectedLimb != null)
{
- var selectedLimb = selectedLimbs.FirstOrDefault();
- if (selectedLimb != null)
+ if (PlayerInput.KeyHit(Keys.C))
{
CopyLimb(selectedLimb);
}
}
}
+ if (ShowExtraRagdollControls && PlayerInput.KeyDown(Keys.LeftControl))
+ {
+ if (PlayerInput.KeyHit(Keys.E))
+ {
+ jointCreationMode = !jointCreationMode;
+ useMouseOffset = true;
+ }
+ }
+ if (jointCreationMode)
+ {
+ createJointButton.HoverColor = Color.LightGreen;
+ createJointButton.Color = Color.LightGreen;
+ }
+ else
+ {
+ createJointButton.HoverColor = Color.White;
+ createJointButton.Color = Color.White;
+ }
UpdateJointCreation();
if (PlayerInput.KeyHit(Keys.Left))
{
@@ -489,20 +550,18 @@ namespace Barotrauma
}
// Camera
Cam.MoveCamera((float)deltaTime, allowMove: false);
- bool movementInput = PlayerInput.KeyDown(InputType.Up) || PlayerInput.KeyDown(InputType.Down) || PlayerInput.KeyDown(InputType.Left) || PlayerInput.KeyDown(InputType.Right);
- // 0.2f, because we want to allow the user to pan when the character is floating in the water without actively moving
- if (!isFreezed && (character.AnimController.Collider.LinearVelocity.LengthSquared() > 0.2f || movementInput))
- {
- // Follow
- Cam.Position = Vector2.SmoothStep(Cam.Position, character.WorldPosition, (float)deltaTime * cameraFollowSpeed);
- }
- else if (PlayerInput.MidButtonHeld())
+ Vector2 targetPos = character.WorldPosition;
+ if (PlayerInput.MidButtonHeld())
{
// Pan
Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 100.0f / Cam.Zoom;
moveSpeed.X = -moveSpeed.X;
- cam.Position += moveSpeed;
+ cameraOffset += moveSpeed;
+ Vector2 max = new Vector2(GameMain.GraphicsWidth * 0.3f, GameMain.GraphicsHeight * 0.38f) / Cam.Zoom;
+ Vector2 min = -max;
+ cameraOffset = Vector2.Clamp(cameraOffset, min, max);
}
+ Cam.Position = targetPos + cameraOffset;
MapEntity.mapEntityList.ForEach(e => e.IsHighlighted = false);
// Update widgets
jointSelectionWidgets.Values.ForEach(w => w.Update((float)deltaTime));
@@ -526,6 +585,11 @@ namespace Barotrauma
}
}
}
+ optionsToggle?.UpdateOpenState((float)deltaTime, new Vector2(optionsPanel.Rect.Width + rightArea.RectTransform.AbsoluteOffset.X, 0), optionsPanel.RectTransform);
+ fileEditToggle?.UpdateOpenState((float)deltaTime, new Vector2(-fileEditPanel.Rect.Width - rightArea.RectTransform.AbsoluteOffset.X, 0), fileEditPanel.RectTransform);
+ characterPanelToggle?.UpdateOpenState((float)deltaTime, new Vector2(-characterSelectionPanel.Rect.Width - rightArea.RectTransform.AbsoluteOffset.X, 0), characterSelectionPanel.RectTransform);
+ modesToggle?.UpdateOpenState((float)deltaTime, new Vector2(-modesPanel.Rect.Width - leftArea.RectTransform.AbsoluteOffset.X, 0), modesPanel.RectTransform);
+ toolsToggle?.UpdateOpenState((float)deltaTime, new Vector2(-toolsPanel.Rect.Width - leftArea.RectTransform.AbsoluteOffset.X, 0), toolsPanel.RectTransform);
}
///
@@ -541,10 +605,6 @@ namespace Barotrauma
scaledMouseSpeed = PlayerInput.MouseSpeedPerSecond * (float)deltaTime;
Cam.UpdateTransform(true);
Submarine.CullEntities(Cam);
-
- // TODO: use the same drawing method as in game?
- //GameMain.GameScreen.DrawMap(graphics, spriteBatch, deltaTime, Cam);
-
Submarine.MainSub.UpdateTransform();
// Lightmaps
@@ -570,7 +630,7 @@ namespace Barotrauma
{
character.AnimController.DebugDraw(spriteBatch);
}
- else if (displayColliders)
+ else if (showColliders)
{
character.AnimController.Collider.DebugDraw(spriteBatch, Color.White, forceColor: true);
character.AnimController.Limbs.ForEach(l => l.body.DebugDraw(spriteBatch, Color.LightGreen, forceColor: true));
@@ -595,7 +655,7 @@ namespace Barotrauma
{
DrawLimbEditor(spriteBatch);
}
- if (showRagdoll)
+ if (editRagdoll || editJoints || editLimbs)
{
DrawRagdoll(spriteBatch, (float)deltaTime);
}
@@ -603,48 +663,51 @@ namespace Barotrauma
{
DrawSpritesheetEditor(spriteBatch, (float)deltaTime);
}
- if (isExtrudingJoint)
+ if (jointCreationMode)
{
- var selectedJoint = selectedJoints.FirstOrDefault();
- if (selectedJoint != null)
+ var textPos = new Vector2(GameMain.GraphicsWidth / 2 - 120, GameMain.GraphicsHeight / 4);
+ if (isExtrudingJoint)
{
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 120, GameMain.GraphicsHeight / 5), GetCharacterEditorTranslation("CreatingNewJoint"), Color.White, font: GUI.LargeFont);
- if (spriteSheetRect.Contains(PlayerInput.MousePosition))
+ var selectedJoint = selectedJoints.LastOrDefault();
+ if (selectedJoint != null)
{
- var startPos = GetLimbSpritesheetRect(selectedJoint.LimbB).Center.ToVector2();
- var offset = ConvertUnits.ToDisplayUnits(selectedJoint.LocalAnchorB) * spriteSheetZoom;
- offset.Y = -offset.Y;
- DrawJointCreationOnSpritesheet(spriteBatch, startPos + offset);
- }
- else
- {
- DrawJointCreationOnRagdoll(spriteBatch, SimToScreen(selectedJoint.WorldAnchorB));
+ GUI.DrawString(spriteBatch, textPos, GetCharacterEditorTranslation("CreatingNewJoint"), Color.White, font: GUI.LargeFont);
+ if (spriteSheetRect.Contains(PlayerInput.MousePosition))
+ {
+ var startPos = GetLimbSpritesheetRect(selectedJoint.LimbB).Center.ToVector2();
+ var offset = ConvertUnits.ToDisplayUnits(selectedJoint.LocalAnchorB) * spriteSheetZoom;
+ offset.Y = -offset.Y;
+ DrawJointCreationOnSpritesheet(spriteBatch, startPos + offset);
+ }
+ else
+ {
+ DrawJointCreationOnRagdoll(spriteBatch, SimToScreen(selectedJoint.WorldAnchorB));
+ }
}
}
- }
- else if (isDrawingJoint)
- {
- var selectedLimb = selectedLimbs.FirstOrDefault();
- if (selectedLimb != null)
+ else if (isDrawingJoint)
{
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 120, GameMain.GraphicsHeight / 5), GetCharacterEditorTranslation("CreatingNewJoint"), Color.White, font: GUI.LargeFont);
- if (spriteSheetRect.Contains(PlayerInput.MousePosition))
+ if (closestSelectedLimb != null)
{
- var startPos = GetLimbSpritesheetRect(selectedLimb).Center.ToVector2();
- if (anchor1Pos.HasValue)
+ GUI.DrawString(spriteBatch, textPos, GetCharacterEditorTranslation("CreatingNewJoint"), Color.White, font: GUI.LargeFont);
+ if (spriteSheetRect.Contains(PlayerInput.MousePosition))
{
- var offset = anchor1Pos.Value;
- offset = -offset;
- startPos += offset;
+ var startPos = GetLimbSpritesheetRect(closestSelectedLimb).Center.ToVector2();
+ if (anchor1Pos.HasValue)
+ {
+ var offset = anchor1Pos.Value;
+ offset = -offset;
+ startPos += offset;
+ }
+ DrawJointCreationOnSpritesheet(spriteBatch, startPos);
+ }
+ else
+ {
+ var startPos = anchor1Pos.HasValue
+ ? SimToScreen(closestSelectedLimb.SimPosition + Vector2.Transform(ConvertUnits.ToSimUnits(anchor1Pos.Value), Matrix.CreateRotationZ(closestSelectedLimb.Rotation)))
+ : SimToScreen(closestSelectedLimb.SimPosition);
+ DrawJointCreationOnRagdoll(spriteBatch, startPos);
}
- DrawJointCreationOnSpritesheet(spriteBatch, startPos);
- }
- else
- {
- var startPos = anchor1Pos.HasValue
- ? SimToScreen(selectedLimb.SimPosition + Vector2.Transform(ConvertUnits.ToSimUnits(anchor1Pos.Value), Matrix.CreateRotationZ(selectedLimb.Rotation)))
- : SimToScreen(selectedLimb.SimPosition);
- DrawJointCreationOnRagdoll(spriteBatch, startPos);
}
}
}
@@ -657,11 +720,11 @@ namespace Barotrauma
GUI.Draw(Cam, spriteBatch);
if (isFreezed)
{
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 35, 100), GetCharacterEditorTranslation("Frozen"), Color.Blue, Color.White * 0.5f, 10, GUI.Font);
+ GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 35, 200), GetCharacterEditorTranslation("Frozen"), Color.Blue, Color.White * 0.5f, 10, GUI.Font);
}
if (animTestPoseToggle.Selected)
{
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 100, 150), GetCharacterEditorTranslation("AnimationTestPoseEnabled"), Color.Blue, Color.White * 0.5f, 10, GUI.Font);
+ GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 100, 300), GetCharacterEditorTranslation("AnimationTestPoseEnabled"), Color.Blue, Color.White * 0.5f, 10, GUI.Font);
}
if (showSpritesheet)
{
@@ -686,20 +749,6 @@ namespace Barotrauma
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 20), $"Cursor Pos: {character.CursorPosition}", Color.White, font: GUI.SmallFont);
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 40), $"Cursor Screen Pos: {PlayerInput.MousePosition}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 80), $"Character World Pos: {character.WorldPosition}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 100), $"Character Pos: {character.Position}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 120), $"Character Sim Pos: {character.SimPosition}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 140), $"Character Draw Pos: {character.DrawPosition}", Color.White, font: GUI.SmallFont);
-
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 180), $"Submarine World Pos: {Submarine.MainSub.WorldPosition}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 200), $"Submarine Pos: {Submarine.MainSub.Position}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 220), $"Submarine Sim Pos: {Submarine.MainSub.Position}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 240), $"Submarine Draw Pos: {Submarine.MainSub.DrawPosition}", Color.White, font: GUI.SmallFont);
-
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 280), $"Movement Limits: MIN: {min} MAX: {max}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 300), $"Clones: {clones.Length}", Color.White, font: GUI.SmallFont);
- //GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2, 320), $"Total amount of walls: {Structure.WallList.Count}", Color.White, font: GUI.SmallFont);
-
// Collider
var collider = character.AnimController.Collider;
var colliderDrawPos = SimToScreen(collider.SimPosition);
@@ -707,8 +756,6 @@ namespace Barotrauma
var endPos = SimToScreen(collider.SimPosition + forward * collider.radius);
GUI.DrawLine(spriteBatch, colliderDrawPos, endPos, Color.LightGreen);
GUI.DrawLine(spriteBatch, colliderDrawPos, SimToScreen(collider.SimPosition + forward * 0.25f), Color.Blue);
- //Vector2 left = Vector2.Transform(-Vector2.UnitX, Matrix.CreateRotationZ(collider.Rotation));
- //Vector2 left = -Vector2.UnitX.TransformVector(forward);
Vector2 left = forward.Left();
GUI.DrawLine(spriteBatch, colliderDrawPos, SimToScreen(collider.SimPosition + left * 0.25f), Color.Red);
ShapeExtensions.DrawCircle(spriteBatch, colliderDrawPos, (endPos - colliderDrawPos).Length(), 40, Color.LightGreen);
@@ -721,12 +768,11 @@ namespace Barotrauma
#region Ragdoll Manipulation
private void UpdateJointCreation()
{
- bool ctrlAlt = PlayerInput.KeyDown(Keys.LeftControl) && PlayerInput.KeyDown(Keys.LeftAlt);
- isExtrudingJoint = !editLimbs && editJoints && ctrlAlt;
- isDrawingJoint = !editJoints && editLimbs && ctrlAlt;
+ isExtrudingJoint = !editLimbs && editJoints && jointCreationMode;
+ isDrawingJoint = !editJoints && editLimbs && jointCreationMode;
if (isExtrudingJoint)
{
- var selectedJoint = selectedJoints.FirstOrDefault();
+ var selectedJoint = selectedJoints.LastOrDefault();
if (selectedJoint != null)
{
if (spriteSheetRect.Contains(PlayerInput.MousePosition))
@@ -758,37 +804,48 @@ namespace Barotrauma
}
else if (isDrawingJoint)
{
- var selectedLimb = selectedLimbs.FirstOrDefault();
- if (selectedLimb != null)
+ if (selectedLimbs.Any())
{
if (spriteSheetRect.Contains(PlayerInput.MousePosition))
{
- if (anchor1Pos == null)
+ if (closestSelectedLimb == null)
{
- anchor1Pos = GetLimbSpritesheetRect(selectedLimb).Center.ToVector2() - PlayerInput.MousePosition;
+ closestSelectedLimb = GetClosestLimbOnSpritesheet(PlayerInput.MousePosition, l => selectedLimbs.Contains(l));
}
- targetLimb = GetClosestLimbOnSpritesheet(PlayerInput.MousePosition, l => l != null && l != selectedLimb && l.ActiveSprite != null);
+ if (anchor1Pos == null && useMouseOffset)
+ {
+ anchor1Pos = GetLimbSpritesheetRect(closestSelectedLimb).Center.ToVector2() - PlayerInput.MousePosition;
+ }
+ targetLimb = GetClosestLimbOnSpritesheet(PlayerInput.MousePosition, l => l != null && l != closestSelectedLimb && l.ActiveSprite != null);
if (targetLimb != null && PlayerInput.LeftButtonClicked())
{
Vector2 anchor1 = anchor1Pos.HasValue ? anchor1Pos.Value / spriteSheetZoom : Vector2.Zero;
anchor1.X = -anchor1.X;
Vector2 anchor2 = (GetLimbSpritesheetRect(targetLimb).Center.ToVector2() - PlayerInput.MousePosition) / spriteSheetZoom;
anchor2.X = -anchor2.X;
- CreateJoint(selectedLimb.limbParams.ID, targetLimb.limbParams.ID, anchor1, anchor2);
+ CreateJoint(closestSelectedLimb.limbParams.ID, targetLimb.limbParams.ID, anchor1, anchor2);
+ jointCreationMode = false;
+ closestSelectedLimb = null;
}
}
else
{
- if (anchor1Pos == null)
+ if (closestSelectedLimb == null)
{
- anchor1Pos = ConvertUnits.ToDisplayUnits(selectedLimb.body.FarseerBody.GetLocalPoint(ScreenToSim(PlayerInput.MousePosition)));
+ closestSelectedLimb = GetClosestLimbOnRagdoll(PlayerInput.MousePosition, l => selectedLimbs.Contains(l));
}
- targetLimb = GetClosestLimbOnRagdoll(PlayerInput.MousePosition, l => l != null && l != selectedLimb && l.ActiveSprite != null);
+ if (anchor1Pos == null && useMouseOffset)
+ {
+ anchor1Pos = ConvertUnits.ToDisplayUnits(closestSelectedLimb.body.FarseerBody.GetLocalPoint(ScreenToSim(PlayerInput.MousePosition)));
+ }
+ targetLimb = GetClosestLimbOnRagdoll(PlayerInput.MousePosition, l => l != null && l != closestSelectedLimb && l.ActiveSprite != null);
if (targetLimb != null && PlayerInput.LeftButtonClicked())
{
Vector2 anchor1 = anchor1Pos ?? Vector2.Zero;
Vector2 anchor2 = ConvertUnits.ToDisplayUnits(targetLimb.body.FarseerBody.GetLocalPoint(ScreenToSim(PlayerInput.MousePosition)));
- CreateJoint(selectedLimb.limbParams.ID, targetLimb.limbParams.ID, anchor1, anchor2);
+ CreateJoint(closestSelectedLimb.limbParams.ID, targetLimb.limbParams.ID, anchor1, anchor2);
+ jointCreationMode = false;
+ closestSelectedLimb = null;
}
}
}
@@ -807,6 +864,7 @@ namespace Barotrauma
private void CopyLimb(Limb limb)
{
+ if (limb == null) { return; }
//RagdollParams.StoreState();
// TODO: copy all params and sub params -> use a generic method?
var rect = limb.ActiveSprite.SourceRect;
@@ -844,6 +902,7 @@ namespace Barotrauma
///
private void ExtrudeJoint(LimbJoint joint, int targetLimb, Vector2? anchor1 = null, Vector2? anchor2 = null)
{
+ if (joint == null) { return; }
CreateJoint(joint.jointParams.Limb2, targetLimb, anchor1, anchor2);
}
@@ -895,6 +954,7 @@ namespace Barotrauma
for (int i = 0; i < selectedJoints.Count; i++)
{
var joint = selectedJoints[i];
+ joint.jointParams.Element.Remove();
RagdollParams.Joints.Remove(joint.jointParams);
}
var removedIDs = new List();
@@ -906,12 +966,11 @@ namespace Barotrauma
break;
}
var limb = selectedLimbs[i];
- //if (limb == character.AnimController.MainLimb)
- //{
- // // TODO: this should be possible now -> test
- // DebugConsole.ThrowError("Can't remove the main limb, because it will crash the game.");
- // continue;
- //}
+ if (limb == character.AnimController.MainLimb)
+ {
+ DebugConsole.ThrowError("Can't remove the main limb, because it will cause unreveratable issues.");
+ continue;
+ }
removedIDs.Add(limb.limbParams.ID);
limb.limbParams.Element.Remove();
RagdollParams.Limbs.Remove(limb.limbParams);
@@ -1201,6 +1260,7 @@ namespace Barotrauma
private void OnPreSpawn()
{
+ cameraOffset = Vector2.Zero;
WayPoint wayPoint = null;
if (!isEndlessRunner)
{
@@ -1289,16 +1349,48 @@ namespace Barotrauma
Cam.Position = character.WorldPosition;
}
- private bool CreateCharacter(string name, string mainFolder, bool isHumanoid, params object[] ragdollConfig)
+ private bool CreateCharacter(string name, string mainFolder, bool isHumanoid, ContentPackage contentPackage = null, params object[] ragdollConfig)
{
- var contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault();
+ var vanilla = GameMain.VanillaContent;
+
if (contentPackage == null)
{
- // This should not normally happen.
+#if DEBUG
+ contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault();
+#else
+ contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault(cp => cp != vanilla);
+#endif
+ }
+ if (contentPackage == null)
+ {
+ string modName = "NewCharacterMod";
+ if (ContentPackage.List.Any(cp => cp.Name == modName))
+ {
+ string tempName = modName;
+ for (int i = 0; i < 100; i++)
+ {
+ tempName = modName + i.ToString();
+ if (ContentPackage.List.None(cp => cp.Name == tempName))
+ {
+ modName = tempName;
+ break;
+ }
+ }
+ }
+ contentPackage = ContentPackage.CreatePackage(modName, Path.Combine(ContentPackage.Folder, $"{modName}.xml"), false);
+ ContentPackage.List.Add(contentPackage);
+ }
+ if (contentPackage == null)
+ {
+ // This should not be possible.
DebugConsole.ThrowError(GetCharacterEditorTranslation("NoContentPackageSelected"));
return false;
}
- var vanilla = GameMain.VanillaContent;
+ if (!GameMain.Config.SelectedContentPackages.Contains(contentPackage))
+ {
+ GameMain.Config.SelectedContentPackages.Add(contentPackage);
+ GameMain.Config.SaveNewPlayerConfig();
+ }
#if !DEBUG
if (vanilla != null && contentPackage == vanilla)
{
@@ -1306,7 +1398,6 @@ namespace Barotrauma
return false;
}
#endif
-
string speciesName = name;
// Config file
string configFilePath = Path.Combine(mainFolder, $"{speciesName}.xml").Replace(@"\", @"/");
@@ -1367,6 +1458,10 @@ namespace Barotrauma
AllFiles.Add(configFilePath);
}
SpawnCharacter(configFilePath, ragdollParams);
+
+ editLimbsToggle.Selected = true;
+ recalculateColliderToggle.Selected = true;
+ selectedLimbs.Add(character.AnimController.Limbs.First());
return true;
}
@@ -1388,61 +1483,355 @@ namespace Barotrauma
#endregion
#region GUI
- private GUIFrame rightPanel;
- private GUIFrame leftPanel;
- private GUIFrame centerPanel;
+ private static Point outerMargin = new Point(0, 0);
+ private static Point innerMargin = new Point(40, 40);
+ private static Color panelColor = new Color(20, 20, 20, 255);
+ private static Color toggleButtonColor = new Color(0.4f, 0.4f, 0.4f, 1);
+
+ private GUIFrame rightArea;
+ private GUIFrame leftArea;
+ private GUIFrame centerArea;
+
+ private GUIFrame characterSelectionPanel;
+ private GUIFrame fileEditPanel;
+ private GUIFrame modesPanel;
+ private GUIFrame toolsPanel;
+ private GUIFrame optionsPanel;
+
private GUIFrame ragdollControls;
+ private GUIFrame jointControls;
private GUIFrame animationControls;
private GUIFrame limbControls;
private GUIFrame spriteSheetControls;
private GUIFrame backgroundColorPanel;
+
private GUIDropDown animSelection;
private GUITickBox freezeToggle;
private GUITickBox animTestPoseToggle;
- private GUITickBox displayCollidersToggle;
+ private GUITickBox showCollidersToggle;
private GUIScrollBar jointScaleBar;
private GUIScrollBar limbScaleBar;
private GUIScrollBar spriteSheetZoomBar;
private GUITickBox copyJointsToggle;
+ private GUITickBox recalculateColliderToggle;
+
private GUITickBox jointsToggle;
private GUITickBox editAnimsToggle;
private GUITickBox editLimbsToggle;
+ private GUITickBox paramsToggle;
+ private GUITickBox spritesheetToggle;
+ private GUITickBox ragdollToggle;
+ private GUITickBox ikToggle;
+ private GUIFrame extraRagdollControls;
+ private GUIButton duplicateLimbButton;
+ private GUIButton deleteSelectedButton;
+ private GUIButton createJointButton;
+
+ private ToggleButton modesToggle;
+ private ToggleButton toolsToggle;
+ private ToggleButton optionsToggle;
+ private ToggleButton characterPanelToggle;
+ private ToggleButton fileEditToggle;
private void CreateGUI()
{
- CreateRightPanel();
- CreateCenterPanel();
- }
-
- private void CreateCenterPanel()
- {
- // Release the old panels
- if (centerPanel != null)
+ // Release the old areas
+ if (rightArea != null)
{
- centerPanel.RectTransform.Parent = null;
+ rightArea.RectTransform.Parent = null;
}
- if (leftPanel != null)
+ if (centerArea != null)
{
- leftPanel.RectTransform.Parent = null;
+ centerArea.RectTransform.Parent = null;
}
- centerPanel = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.TopRight)
+ if (leftArea != null)
{
- AbsoluteOffset = new Point((int)(rightPanel.RectTransform.ScaledSize.X + rightPanel.RectTransform.RelativeOffset.X * rightPanel.RectTransform.Parent.ScaledSize.X + 20), 20)
+ leftArea.RectTransform.Parent = null;
+ }
+ // Create the areas
+ rightArea = new GUIFrame(new RectTransform(new Vector2(0.15f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.CenterRight)
+ {
+ AbsoluteOffset = new Point(outerMargin.X, 0)
}, style: null) { CanBeFocused = false };
- leftPanel = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.CenterLeft)
+ centerArea = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.TopRight)
{
- AbsoluteOffset = new Point(20, 0)
+ AbsoluteOffset = new Point((int)(rightArea.RectTransform.ScaledSize.X + rightArea.RectTransform.RelativeOffset.X * rightArea.RectTransform.Parent.ScaledSize.X + 20), outerMargin.Y + 20)
+
+ }, style: null)
+ { CanBeFocused = false };
+ leftArea = new GUIFrame(new RectTransform(new Vector2(0.2f, 0.95f), parent: Frame.RectTransform, anchor: Anchor.CenterLeft)
+ {
+ AbsoluteOffset = new Point(outerMargin.X, 0)
}, style: null)
{
CanBeFocused = false
};
+
+ Vector2 buttonSize = new Vector2(1, 0.04f);
+ Vector2 toggleSize = new Vector2(0.03f, 0.03f);
+
+ CreateCharacterSelectionPanel();
+ CreateModesPanel(toggleSize);
+ CreateToolsPanel();
+ CreateFileEditPanel();
+ CreateOptionsPanel(toggleSize);
+ CreateContextualControls();
+ }
+
+ private void CreateModesPanel(Vector2 toggleSize)
+ {
+ modesPanel = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.3f), leftArea.RectTransform, Anchor.BottomLeft), style: null, color: panelColor);
+ var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(modesPanel.Rect.Width - innerMargin.X, modesPanel.Rect.Height - innerMargin.Y),
+ modesPanel.RectTransform, Anchor.Center))
+ {
+ AbsoluteSpacing = 2,
+ Stretch = true
+ };
+
+ new GUITextBlock(new RectTransform(new Vector2(0.03f, 0.06f), layoutGroup.RectTransform), GetCharacterEditorTranslation("ModesPanel"), font: GUI.LargeFont);
+ // Main modes
+ editLimbsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditLimbs")) { Selected = editLimbs };
+ jointsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditJoints")) { Selected = editJoints };
+ editAnimsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditAnimations")) { Selected = editAnimations };
+ // Spacing
+ new GUIFrame(new RectTransform(toggleSize, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
+ // Minor modes
+ ragdollToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowRagdoll")) { Selected = editRagdoll };
+ paramsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowParameters")) { Selected = showParamsEditor };
+ spritesheetToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowSpriteSheet")) { Selected = showSpritesheet };
+ showCollidersToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowColliders"))
+ {
+ Selected = showColliders,
+ OnSelected = box =>
+ {
+ showColliders = box.Selected;
+ return true;
+ }
+ };
+ ikToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditIKTargets")) { Selected = editIK };
+ editAnimsToggle.OnSelected = box =>
+ {
+ editAnimations = box.Selected;
+ if (editAnimations)
+ {
+ SetToggle(editLimbsToggle, false);
+ SetToggle(jointsToggle, false);
+ spritesheetToggle.Selected = false;
+ ClearSelection();
+ }
+ ResetParamsEditor();
+ return true;
+ };
+ paramsToggle.OnSelected = box =>
+ {
+ showParamsEditor = box.Selected;
+ return true;
+ };
+ editLimbsToggle.OnSelected = box =>
+ {
+ editLimbs = box.Selected;
+ if (editLimbs)
+ {
+ SetToggle(editAnimsToggle, false);
+ SetToggle(jointsToggle, false);
+ spritesheetToggle.Selected = true;
+ ClearSelection();
+ }
+ ResetParamsEditor();
+ return true;
+ };
+ ragdollToggle.OnSelected = box =>
+ {
+ editRagdoll = box.Selected;
+ if (editRagdoll)
+ {
+ if (!editIK)
+ {
+ paramsToggle.Selected = true;
+ }
+ ClearSelection();
+ }
+ ResetParamsEditor();
+ return true;
+ };
+ jointsToggle.OnSelected = box =>
+ {
+ editJoints = box.Selected;
+ if (editJoints)
+ {
+ SetToggle(editLimbsToggle, false);
+ SetToggle(editAnimsToggle, false);
+ ikToggle.Selected = false;
+ spritesheetToggle.Selected = true;
+ ClearSelection();
+ }
+ ResetParamsEditor();
+ return true;
+ };
+ ikToggle.OnSelected = box =>
+ {
+ editIK = box.Selected;
+ if (editIK)
+ {
+ ragdollToggle.Selected = true;
+ }
+ return true;
+ };
+ spritesheetToggle.OnSelected = box =>
+ {
+ showSpritesheet = box.Selected;
+ return true;
+ };
+ modesToggle = new ToggleButton(new RectTransform(new Vector2(0.125f, 1), modesPanel.RectTransform, Anchor.CenterRight, Pivot.CenterLeft), Direction.Left);
+ }
+
+ private void SetToggle(GUITickBox toggle, bool value)
+ {
+ if (toggle.Selected != value)
+ {
+ if (value)
+ {
+ toggle.Box.Flash(Color.LightGreen, useRectangleFlash: true);
+ }
+ else
+ {
+ toggle.Box.Flash(Color.Red, useRectangleFlash: true);
+ }
+ }
+ toggle.Selected = value;
+ }
+
+ private void CreateToolsPanel()
+ {
+ Vector2 buttonSize = new Vector2(1, 0.06f);
+ toolsPanel = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.15f), leftArea.RectTransform, Anchor.CenterLeft)
+ {
+ RelativeOffset = new Vector2(0, 0.1f)
+ }, style: null, color: panelColor);
+ var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(toolsPanel.Rect.Width - innerMargin.X, toolsPanel.Rect.Height - innerMargin.Y),
+ toolsPanel.RectTransform, Anchor.Center))
+ {
+ AbsoluteSpacing = 2,
+ Stretch = true
+ };
+ new GUITextBlock(new RectTransform(new Vector2(0.03f, 0.06f), layoutGroup.RectTransform), GetCharacterEditorTranslation("ToolsPanel"), font: GUI.LargeFont);
+ var reloadTexturesButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ReloadTextures"));
+ reloadTexturesButton.OnClicked += (button, userData) =>
+ {
+ foreach (var limb in character.AnimController.Limbs)
+ {
+ limb.ActiveSprite.ReloadTexture();
+ limb.WearingItems.ForEach(i => i.Sprite.ReloadTexture());
+ limb.OtherWearables.ForEach(w => w.Sprite.ReloadTexture());
+ }
+ CreateTextures();
+ return true;
+ };
+ new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("RecreateRagdoll"))
+ {
+ ToolTip = GetCharacterEditorTranslation("RecreateRagdollTooltip"),
+ OnClicked = (button, data) =>
+ {
+ RecreateRagdoll();
+ character.AnimController.ResetLimbs();
+ return true;
+ }
+ };
+
+ toolsToggle = new ToggleButton(new RectTransform(new Vector2(0.125f, 1), toolsPanel.RectTransform, Anchor.CenterRight, Pivot.CenterLeft), Direction.Left);
+ }
+
+ private void CreateOptionsPanel(Vector2 toggleSize)
+ {
+ optionsPanel = new GUIFrame(new RectTransform(new Vector2(1, 0.3f), rightArea.RectTransform, Anchor.Center)
+ {
+ RelativeOffset = new Vector2(0, -0.075f)
+ }, style: null, color: panelColor);
+ var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(optionsPanel.Rect.Width - innerMargin.X, optionsPanel.Rect.Height - innerMargin.Y),
+ optionsPanel.RectTransform, Anchor.Center))
+ {
+ AbsoluteSpacing = 2,
+ Stretch = true
+ };
+
+ new GUITextBlock(new RectTransform(new Vector2(0.03f, 0.06f), layoutGroup.RectTransform), GetCharacterEditorTranslation("OptionsPanel"), font: GUI.LargeFont);
+ freezeToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("Freeze")) { Selected = isFreezed };
+ var autoFreezeToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("AutoFreeze")) { Selected = autoFreeze };
+ var limbPairEditToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("LimbPairEditing"))
+ {
+ Selected = limbPairEditing,
+ Enabled = character.IsHumanoid // TODO: remove when limb pair editing works for non-humanoids
+ };
+ animTestPoseToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("AnimationTestPose"))
+ {
+ Selected = character.AnimController.AnimationTestPose,
+ Enabled = character.IsHumanoid
+ };
+ new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("AutoMove"))
+ {
+ Selected = character.OverrideMovement != null,
+ OnSelected = box =>
+ {
+ character.OverrideMovement = box.Selected ? new Vector2(1, 0) as Vector2? : null;
+ return true;
+ }
+ };
+ new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("FollowCursor"))
+ {
+ Selected = !character.dontFollowCursor,
+ OnSelected = box =>
+ {
+ character.dontFollowCursor = !box.Selected;
+ return true;
+ }
+ };
+ new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditBackgroundColor"))
+ {
+ Selected = displayBackgroundColor,
+ OnSelected = box =>
+ {
+ displayBackgroundColor = box.Selected;
+ return true;
+ }
+ };
+ freezeToggle.OnSelected = box =>
+ {
+ isFreezed = box.Selected;
+ return true;
+ };
+ autoFreezeToggle.OnSelected = box =>
+ {
+ autoFreeze = box.Selected;
+ return true;
+ };
+ limbPairEditToggle.OnSelected = box =>
+ {
+ limbPairEditing = box.Selected;
+ return true;
+ };
+ animTestPoseToggle.OnSelected = box =>
+ {
+ character.AnimController.AnimationTestPose = box.Selected;
+ return true;
+ };
+ optionsToggle = new ToggleButton(new RectTransform(new Vector2(0.1f, 1), optionsPanel.RectTransform, Anchor.CenterLeft, Pivot.CenterRight), Direction.Right);
+ }
+
+ private void CreateContextualControls()
+ {
Point elementSize = new Point(120, 20);
int textAreaHeight = 20;
// General controls
- backgroundColorPanel = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), centerPanel.RectTransform, Anchor.TopRight), style: null) { CanBeFocused = false };
+ backgroundColorPanel = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), centerArea.RectTransform, Anchor.TopRight)
+ {
+ AbsoluteOffset = new Point(10, 0)
+ }, style: null)
+ {
+ CanBeFocused = false
+ };
// Background color
- var frame = new GUIFrame(new RectTransform(new Point(400, 80), backgroundColorPanel.RectTransform, Anchor.TopRight), style: null, color: Color.Black * 0.4f);
+ var frame = new GUIFrame(new RectTransform(new Point(500, 80), backgroundColorPanel.RectTransform, Anchor.TopRight), style: null, color: Color.Black * 0.4f);
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1), frame.RectTransform) { MinSize = new Point(80, 26) }, GetCharacterEditorTranslation("BackgroundColor") + ":", textColor: Color.WhiteSmoke);
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 1), frame.RectTransform, Anchor.TopRight)
{
@@ -1456,7 +1845,7 @@ namespace Barotrauma
string[] colorComponentLabels = { "R", "G", "B" };
for (int i = 2; i >= 0; i--)
{
- var element = new GUIFrame(new RectTransform(new Vector2(0.2f, 1), inputArea.RectTransform)
+ var element = new GUIFrame(new RectTransform(new Vector2(0.3f, 1), inputArea.RectTransform)
{
MinSize = new Point(40, 0),
MaxSize = new Point(100, 50)
@@ -1464,7 +1853,7 @@ namespace Barotrauma
var colorLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), colorComponentLabels[i],
font: GUI.SmallFont, textAlignment: Alignment.CenterLeft);
GUINumberInput numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight),
- GUINumberInput.NumberType.Int)
+ GUINumberInput.NumberType.Int, relativeButtonAreaWidth: 0.25f)
{
Font = GUI.SmallFont
};
@@ -1476,22 +1865,25 @@ namespace Barotrauma
case 0:
colorLabel.TextColor = Color.Red;
numberInput.IntValue = backgroundColor.R;
- numberInput.OnValueChanged += (numInput) => backgroundColor.R = (byte)(numInput.IntValue);
+ numberInput.OnValueChanged += (numInput) => backgroundColor.R = (byte)numInput.IntValue;
break;
case 1:
colorLabel.TextColor = Color.LightGreen;
numberInput.IntValue = backgroundColor.G;
- numberInput.OnValueChanged += (numInput) => backgroundColor.G = (byte)(numInput.IntValue);
+ numberInput.OnValueChanged += (numInput) => backgroundColor.G = (byte)numInput.IntValue;
break;
case 2:
colorLabel.TextColor = Color.DeepSkyBlue;
numberInput.IntValue = backgroundColor.B;
- numberInput.OnValueChanged += (numInput) => backgroundColor.B = (byte)(numInput.IntValue);
+ numberInput.OnValueChanged += (numInput) => backgroundColor.B = (byte)numInput.IntValue;
break;
}
}
// Spritesheet controls
- spriteSheetControls = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), centerPanel.RectTransform, Anchor.BottomLeft), style: null)
+ spriteSheetControls = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), centerArea.RectTransform, Anchor.BottomLeft)
+ {
+ RelativeOffset = new Vector2(0, 0.05f)
+ }, style: null)
{
CanBeFocused = false
};
@@ -1509,7 +1901,7 @@ namespace Barotrauma
return true;
}
};
- new GUIButton(new RectTransform(new Vector2(0.2f, 1), spriteSheetControlElement.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("Reset"))
+ new GUIButton(new RectTransform(new Vector2(0.3f, 1), spriteSheetControlElement.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("Reset"))
{
OnClicked = (box, data) =>
{
@@ -1558,7 +1950,7 @@ namespace Barotrauma
// }
//};
// Limb controls
- limbControls = new GUIFrame(new RectTransform(Vector2.One, centerPanel.RectTransform), style: null) { CanBeFocused = false };
+ limbControls = new GUIFrame(new RectTransform(Vector2.One, centerArea.RectTransform), style: null) { CanBeFocused = false };
var layoutGroupLimbControls = new GUILayoutGroup(new RectTransform(Vector2.One, limbControls.RectTransform), childAnchor: Anchor.TopLeft) { CanBeFocused = false };
var lockSpriteOriginToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupLimbControls.RectTransform), GetCharacterEditorTranslation("LockSpriteOrigin"))
{
@@ -1590,32 +1982,22 @@ namespace Barotrauma
}
};
lockSpriteSizeToggle.TextColor = Color.White;
- var recalculateColliderToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupLimbControls.RectTransform), GetCharacterEditorTranslation("AdjustCollider"))
+ recalculateColliderToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupLimbControls.RectTransform), GetCharacterEditorTranslation("AdjustCollider"))
{
Selected = recalculateCollider,
OnSelected = (GUITickBox box) =>
{
recalculateCollider = box.Selected;
- displayCollidersToggle.Selected = recalculateCollider;
+ showCollidersToggle.Selected = recalculateCollider;
return true;
}
};
recalculateColliderToggle.TextColor = Color.White;
- // Ragdoll
+ // Joint controls
Point sliderSize = new Point(300, 20);
- ragdollControls = new GUIFrame(new RectTransform(Vector2.One, centerPanel.RectTransform), style: null) { CanBeFocused = false };
- var layoutGroupRagdoll = new GUILayoutGroup(new RectTransform(Vector2.One, ragdollControls.RectTransform), childAnchor: Anchor.TopLeft) { CanBeFocused = false };
- var uniformScalingToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupRagdoll.RectTransform), GetCharacterEditorTranslation("UniformScale"))
- {
- Selected = uniformScaling,
- OnSelected = (GUITickBox box) =>
- {
- uniformScaling = box.Selected;
- return true;
- }
- };
- uniformScalingToggle.TextColor = Color.White;
- copyJointsToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupRagdoll.RectTransform), GetCharacterEditorTranslation("CopyJointSettings"))
+ jointControls = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.075f), centerArea.RectTransform), style: null) { CanBeFocused = false };
+ var layoutGroupJoints = new GUILayoutGroup(new RectTransform(Vector2.One, jointControls.RectTransform), childAnchor: Anchor.TopLeft) { CanBeFocused = false };
+ copyJointsToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupJoints.RectTransform), GetCharacterEditorTranslation("CopyJointSettings"))
{
ToolTip = GetCharacterEditorTranslation("CopyJointSettingsTooltip"),
Selected = copyJointSettings,
@@ -1627,8 +2009,19 @@ namespace Barotrauma
return true;
}
};
- // Spacing
- new GUIFrame(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupRagdoll.RectTransform), style: null) { CanBeFocused = false };
+ // Ragdoll controls
+ ragdollControls = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.25f), centerArea.RectTransform) { AbsoluteOffset = new Point(0, jointControls.Rect.Bottom) }, style: null) { CanBeFocused = false };
+ var layoutGroupRagdoll = new GUILayoutGroup(new RectTransform(Vector2.One, ragdollControls.RectTransform), childAnchor: Anchor.TopLeft) { CanBeFocused = false };
+ var uniformScalingToggle = new GUITickBox(new RectTransform(new Point(elementSize.X, textAreaHeight), layoutGroupRagdoll.RectTransform), GetCharacterEditorTranslation("UniformScale"))
+ {
+ Selected = uniformScaling,
+ OnSelected = (GUITickBox box) =>
+ {
+ uniformScaling = box.Selected;
+ return true;
+ }
+ };
+ uniformScalingToggle.TextColor = Color.White;
var jointScaleElement = new GUIFrame(new RectTransform(sliderSize + new Point(0, textAreaHeight), layoutGroupRagdoll.RectTransform), style: null);
var jointScaleText = new GUITextBlock(new RectTransform(new Point(elementSize.X, textAreaHeight), jointScaleElement.RectTransform), $"{GetCharacterEditorTranslation("JointScale")}: {RagdollParams.JointScale.FormatDoubleDecimal()}", Color.WhiteSmoke, textAlignment: Alignment.Center);
var limbScaleElement = new GUIFrame(new RectTransform(sliderSize + new Point(0, textAreaHeight), layoutGroupRagdoll.RectTransform), style: null);
@@ -1695,8 +2088,44 @@ namespace Barotrauma
ragdollResetRequiresForceLoading = true;
return true;
};
+
+ // Ragdoll manipulation
+ extraRagdollControls = new GUIFrame(new RectTransform(new Point(140, 30), centerArea.RectTransform, Anchor.BottomRight)
+ {
+ RelativeOffset = new Vector2(0.2f, 0.15f)
+ }, style: null)
+ {
+ CanBeFocused = false
+ };
+ var extraRagdollLayout = new GUILayoutGroup(new RectTransform(Vector2.One, extraRagdollControls.RectTransform));
+ duplicateLimbButton = new GUIButton(new RectTransform(new Point(140, 30), extraRagdollLayout.RectTransform), "Duplicate Limb")
+ {
+ OnClicked = (button, data) =>
+ {
+ CopyLimb(selectedLimbs.FirstOrDefault());
+ return true;
+ }
+ };
+ deleteSelectedButton = new GUIButton(new RectTransform(new Point(140, 30), extraRagdollLayout.RectTransform), "Delete Selected")
+ {
+ OnClicked = (button, data) =>
+ {
+ DeleteSelected();
+ return true;
+ }
+ };
+ createJointButton = new GUIButton(new RectTransform(new Point(140, 30), extraRagdollLayout.RectTransform), "Create Joint")
+ {
+ OnClicked = (button, data) =>
+ {
+ jointCreationMode = !jointCreationMode;
+ useMouseOffset = false;
+ return true;
+ }
+ };
+
// Animation
- animationControls = new GUIFrame(new RectTransform(Vector2.One, centerPanel.RectTransform), style: null) { CanBeFocused = false };
+ animationControls = new GUIFrame(new RectTransform(Vector2.One, centerArea.RectTransform), style: null) { CanBeFocused = false };
var layoutGroupAnimation = new GUILayoutGroup(new RectTransform(Vector2.One, animationControls.RectTransform), childAnchor: Anchor.TopLeft) { CanBeFocused = false };
var animationSelectionElement = new GUIFrame(new RectTransform(new Point(elementSize.X * 2 - 5, elementSize.Y), layoutGroupAnimation.RectTransform), style: null);
var animationSelectionText = new GUITextBlock(new RectTransform(new Point(elementSize.X, elementSize.Y), animationSelectionElement.RectTransform), GetCharacterEditorTranslation("SelectedAnimation") + ": ", Color.WhiteSmoke, textAlignment: Alignment.Center);
@@ -1769,31 +2198,30 @@ namespace Barotrauma
};
}
- private void CreateRightPanel()
+ private void CreateCharacterSelectionPanel()
{
- // Release the old panel
- if (rightPanel != null)
+ characterSelectionPanel = new GUIFrame(new RectTransform(new Vector2(1, 0.25f), rightArea.RectTransform, Anchor.TopRight), style: null, color: panelColor);
+ var padding = new GUIFrame(new RectTransform(new Point(characterSelectionPanel.Rect.Width - innerMargin.X, characterSelectionPanel.Rect.Height - innerMargin.Y),
+ characterSelectionPanel.RectTransform, Anchor.Center), style: null)
{
- rightPanel.RectTransform.Parent = null;
- }
- Vector2 buttonSize = new Vector2(1, 0.04f);
- Vector2 toggleSize = new Vector2(0.03f, 0.03f);
- Point margin = new Point(40, 60);
- rightPanel = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), parent: Frame.RectTransform, anchor: Anchor.CenterRight), style: "GUIFrameRight");
- var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(rightPanel.Rect.Width - margin.X, rightPanel.Rect.Height - margin.Y), rightPanel.RectTransform, Anchor.Center))
- {
- Stretch = true
+ CanBeFocused = false
};
- var disclaimerBtnHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.04f), layoutGroup.RectTransform), style: null);
-
+ // Disclaimer
+ var disclaimerBtnHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), padding.RectTransform), style: null);
var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), disclaimerBtnHolder.RectTransform, Anchor.TopRight), style: "GUINotificationButton")
{
OnClicked = (btn, userdata) => { GameMain.Instance.ShowEditorDisclaimer(); return true; }
};
disclaimerBtn.RectTransform.MaxSize = new Point(disclaimerBtn.Rect.Height);
- var characterDropDown = new GUIDropDown(new RectTransform(new Vector2(1, 0.04f), layoutGroup.RectTransform), elementCount: 10, style: null);
+ // Character selection
+ new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.2f), padding.RectTransform), GetCharacterEditorTranslation("CharacterPanel"), font: GUI.LargeFont);
+
+ var characterDropDown = new GUIDropDown(new RectTransform(new Vector2(1, 0.2f), padding.RectTransform)
+ {
+ RelativeOffset = new Vector2(0, 0.2f)
+ }, elementCount: 8, style: null);
characterDropDown.ListBox.Color = new Color(characterDropDown.ListBox.Color.R, characterDropDown.ListBox.Color.G, characterDropDown.ListBox.Color.B, byte.MaxValue);
foreach (var file in AllFiles)
{
@@ -1807,7 +2235,10 @@ namespace Barotrauma
};
if (currentCharacterConfig == Character.HumanConfigFile)
{
- var jobDropDown = new GUIDropDown(new RectTransform(new Vector2(1, 0.04f), layoutGroup.RectTransform), elementCount: 7, style: null);
+ var jobDropDown = new GUIDropDown(new RectTransform(new Vector2(1, 0.15f), padding.RectTransform)
+ {
+ RelativeOffset = new Vector2(0, 0.45f)
+ }, elementCount: 8, style: null);
jobDropDown.ListBox.Color = new Color(jobDropDown.ListBox.Color.R, jobDropDown.ListBox.Color.G, jobDropDown.ListBox.Color.B, byte.MaxValue);
jobDropDown.AddItem("None");
JobPrefab.List.ForEach(j => jobDropDown.AddItem(j.Name, j.Identifier));
@@ -1823,7 +2254,7 @@ namespace Barotrauma
return true;
};
}
- var charButtons = new GUIFrame(new RectTransform(new Vector2(buttonSize.X, buttonSize.Y * 1.5f), parent: layoutGroup.RectTransform), style: null);
+ var charButtons = new GUIFrame(new RectTransform(new Vector2(1, 0.25f), parent: padding.RectTransform, anchor: Anchor.BottomLeft), style: null);
var prevCharacterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), charButtons.RectTransform, Anchor.TopLeft), GetCharacterEditorTranslation("PreviousCharacter"));
prevCharacterButton.TextBlock.AutoScale = true;
prevCharacterButton.OnClicked += (b, obj) =>
@@ -1838,133 +2269,27 @@ namespace Barotrauma
SpawnCharacter(GetNextConfigFile());
return true;
};
- var paramsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowParameters")) { Selected = showParamsEditor };
- var spritesheetToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowSpriteSheet")) { Selected = showSpritesheet };
- var ragdollToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ShowRagdoll")) { Selected = showRagdoll };
- editAnimsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditAnimations")) { Selected = editAnimations };
- editLimbsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditLimbs")) { Selected = editLimbs };
- jointsToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditJoints")) { Selected = editJoints };
- var ikToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditIKTargets")) { Selected = editIK };
- freezeToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("Freeze")) { Selected = isFreezed };
- var autoFreezeToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("AutoFreeze")) { Selected = autoFreeze };
- var limbPairEditToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("LimbPairEditing")) { Selected = limbPairEditing };
- animTestPoseToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("AnimationTestPose")) { Selected = character.AnimController.AnimationTestPose };
- editAnimsToggle.OnSelected = box =>
+ characterPanelToggle = new ToggleButton(new RectTransform(new Vector2(0.1f, 1), characterSelectionPanel.RectTransform, Anchor.CenterLeft, Pivot.CenterRight), Direction.Right);
+ }
+
+ private void CreateFileEditPanel()
+ {
+ Vector2 buttonSize = new Vector2(1, 0.04f);
+
+ fileEditPanel = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), rightArea.RectTransform, Anchor.BottomRight), style: null, color: panelColor);
+ var layoutGroup = new GUILayoutGroup(new RectTransform(new Point(fileEditPanel.Rect.Width - innerMargin.X, fileEditPanel.Rect.Height - innerMargin.Y),
+ fileEditPanel.RectTransform, Anchor.Center))
{
- editAnimations = box.Selected;
- if (editAnimations)
- {
- spritesheetToggle.Selected = false;
- editLimbsToggle.Selected = false;
- jointsToggle.Selected = false;
- ResetParamsEditor();
- }
- return true;
- };
- paramsToggle.OnSelected = box =>
- {
- showParamsEditor = box.Selected;
- return true;
- };
- editLimbsToggle.OnSelected = box =>
- {
- editLimbs = box.Selected;
- if (editLimbs)
- {
- editAnimsToggle.Selected = false;
- jointsToggle.Selected = false;
- spritesheetToggle.Selected = true;
- ResetParamsEditor();
- }
- return true;
- };
- ragdollToggle.OnSelected = box => showRagdoll = box.Selected;
- jointsToggle.OnSelected = box =>
- {
- editJoints = box.Selected;
- if (editJoints)
- {
- editLimbsToggle.Selected = false;
- editAnimsToggle.Selected = false;
- ikToggle.Selected = false;
- spritesheetToggle.Selected = true;
- ragdollToggle.Selected = true;
- ResetParamsEditor();
- }
- return true;
- };
- ikToggle.OnSelected = box =>
- {
- editIK = box.Selected;
- if (editIK)
- {
- ragdollToggle.Selected = true;
- }
- return true;
- };
- spritesheetToggle.OnSelected = box =>
- {
- showSpritesheet = box.Selected;
- return true;
- };
- freezeToggle.OnSelected = box =>
- {
- isFreezed = box.Selected;
- return true;
- };
- autoFreezeToggle.OnSelected = box =>
- {
- autoFreeze = box.Selected;
- return true;
- };
- limbPairEditToggle.OnSelected = box =>
- {
- limbPairEditing = box.Selected;
- return true;
- };
- animTestPoseToggle.OnSelected = box =>
- {
- character.AnimController.AnimationTestPose = box.Selected;
- return true;
- };
- new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("AutoMove"))
- {
- Selected = character.OverrideMovement != null,
- OnSelected = box =>
- {
- character.OverrideMovement = box.Selected ? new Vector2(1, 0) as Vector2? : null;
- return true;
- }
- };
- new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("FollowCursor"))
- {
- Selected = !character.dontFollowCursor,
- OnSelected = box =>
- {
- character.dontFollowCursor = !box.Selected;
- return true;
- }
- };
- displayCollidersToggle = new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("DisplayColliders"))
- {
- Selected = displayColliders,
- OnSelected = box =>
- {
- displayColliders = box.Selected;
- return true;
- }
- };
- new GUITickBox(new RectTransform(toggleSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("EditBackgroundColor"))
- {
- Selected = displayBackgroundColor,
- OnSelected = box =>
- {
- displayBackgroundColor = box.Selected;
- return true;
- }
+ AbsoluteSpacing = 1,
+ Stretch = true
};
+ new GUITextBlock(new RectTransform(new Vector2(0.03f, 0.06f), layoutGroup.RectTransform), GetCharacterEditorTranslation("FileEditPanel"), font: GUI.LargeFont);
+
+ // Spacing
+ new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
var quickSaveAnimButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("QuickSaveAnimations"));
+ quickSaveAnimButton.Color = Color.LightGreen;
quickSaveAnimButton.OnClicked += (button, userData) =>
{
#if !DEBUG
@@ -1980,6 +2305,7 @@ namespace Barotrauma
return true;
};
var quickSaveRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("QuickSaveRagdoll"));
+ quickSaveRagdollButton.Color = Color.LightGreen;
quickSaveRagdollButton.OnClicked += (button, userData) =>
{
#if !DEBUG
@@ -1994,52 +2320,8 @@ namespace Barotrauma
GUI.AddMessage(GetCharacterEditorTranslation("RagdollSavedTo").Replace("[path]", RagdollParams.FullPath), Color.Green, font: GUI.Font);
return true;
};
- var resetAnimButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ResetAnimations"));
- resetAnimButton.OnClicked += (button, userData) =>
- {
- AnimParams.ForEach(p => p.Reset(true));
- ResetParamsEditor();
- GUI.AddMessage(GetCharacterEditorTranslation("AllAnimationsReset"), Color.WhiteSmoke, font: GUI.Font);
- animationResetRequiresForceLoading = false;
- return true;
- };
- var resetRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ResetRagdoll"));
- resetRagdollButton.OnClicked += (button, userData) =>
- {
- if (ragdollResetRequiresForceLoading)
- {
- character.AnimController.ResetRagdoll(forceReload: true);
- RecreateRagdoll();
- ragdollResetRequiresForceLoading = false;
- }
- else
- {
- character.AnimController.ResetRagdoll(forceReload: false);
- // For some reason Enumerable.Contains() method does not find the match, threfore the conversion to a list.
- var selectedJointParams = selectedJoints.Select(j => j.jointParams).ToList();
- var selectedLimbParams = selectedLimbs.Select(l => l.limbParams).ToList();
- ClearWidgets();
- ClearSelection();
- foreach (var joint in character.AnimController.LimbJoints)
- {
- if (selectedJointParams.Contains(joint.jointParams))
- {
- selectedJoints.Add(joint);
- }
- }
- foreach (var limb in character.AnimController.Limbs)
- {
- if (selectedLimbParams.Contains(limb.limbParams))
- {
- selectedLimbs.Add(limb);
- }
- }
- ResetParamsEditor();
- }
- CreateGUI();
- GUI.AddMessage(GetCharacterEditorTranslation("RagdollReset"), Color.WhiteSmoke, font: GUI.Font);
- return true;
- };
+ // Spacing
+ new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
Vector2 messageBoxRelSize = new Vector2(0.5f, 0.5f);
int messageBoxWidth = GameMain.GraphicsWidth / 2;
int messageBoxHeight = GameMain.GraphicsHeight / 2;
@@ -2152,7 +2434,7 @@ namespace Barotrauma
ragdoll.Reset(true);
GUI.AddMessage(GetCharacterEditorTranslation("RagdollLoadedFrom").Replace("[file]", selectedFile), Color.WhiteSmoke, font: GUI.Font);
RecreateRagdoll(ragdoll);
- CreateCenterPanel();
+ CreateContextualControls();
loadBox.Close();
return true;
};
@@ -2348,28 +2630,62 @@ namespace Barotrauma
};
return true;
};
- var reloadTexturesButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ReloadTextures"));
- reloadTexturesButton.OnClicked += (button, userData) =>
+
+ // Spacing
+ new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
+ var resetAnimButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ResetAnimations"));
+ resetAnimButton.Color = Color.Red;
+ resetAnimButton.OnClicked += (button, userData) =>
{
- foreach (var limb in character.AnimController.Limbs)
- {
- limb.ActiveSprite.ReloadTexture();
- limb.WearingItems.ForEach(i => i.Sprite.ReloadTexture());
- limb.OtherWearables.ForEach(w => w.Sprite.ReloadTexture());
- }
- CreateTextures();
+ AnimParams.ForEach(p => p.Reset(true));
+ ResetParamsEditor();
+ GUI.AddMessage(GetCharacterEditorTranslation("AllAnimationsReset"), Color.WhiteSmoke, font: GUI.Font);
+ animationResetRequiresForceLoading = false;
return true;
};
- new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("RecreateRagdoll"))
+ var resetRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("ResetRagdoll"));
+ resetRagdollButton.Color = Color.Red;
+ resetRagdollButton.OnClicked += (button, userData) =>
{
- ToolTip = GetCharacterEditorTranslation("RecreateRagdollTooltip"),
- OnClicked = (button, data) =>
+ if (ragdollResetRequiresForceLoading)
{
+ character.AnimController.ResetRagdoll(forceReload: true);
RecreateRagdoll();
- character.AnimController.ResetLimbs();
- return true;
+ ragdollResetRequiresForceLoading = false;
}
+ else
+ {
+ character.AnimController.ResetRagdoll(forceReload: false);
+ // For some reason Enumerable.Contains() method does not find the match, threfore the conversion to a list.
+ var selectedJointParams = selectedJoints.Select(j => j.jointParams).ToList();
+ var selectedLimbParams = selectedLimbs.Select(l => l.limbParams).ToList();
+ ClearWidgets();
+ ClearSelection();
+ foreach (var joint in character.AnimController.LimbJoints)
+ {
+ if (selectedJointParams.Contains(joint.jointParams))
+ {
+ selectedJoints.Add(joint);
+ }
+ }
+ foreach (var limb in character.AnimController.Limbs)
+ {
+ if (selectedLimbParams.Contains(limb.limbParams))
+ {
+ selectedLimbs.Add(limb);
+ }
+ }
+ ResetParamsEditor();
+ }
+ jointCreationMode = false;
+ closestSelectedLimb = null;
+ CreateGUI();
+ GUI.AddMessage(GetCharacterEditorTranslation("RagdollReset"), Color.WhiteSmoke, font: GUI.Font);
+ return true;
};
+
+ // Spacing
+ new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("CreateNewCharacter"))
{
OnClicked = (button, data) =>
@@ -2379,13 +2695,82 @@ namespace Barotrauma
spritesheetToggle.Selected = false;
jointsToggle.Selected = false;
paramsToggle.Selected = false;
+ ragdollToggle.Selected = false;
Wizard.Instance.SelectTab(Wizard.Tab.Character);
return true;
}
};
+
+ fileEditToggle = new ToggleButton(new RectTransform(new Vector2(0.1f, 1), fileEditPanel.RectTransform, Anchor.CenterLeft, Pivot.CenterRight), Direction.Right);
}
#endregion
+ #region ToggleButtons
+
+ private enum Direction
+ {
+ Left,
+ Right
+ }
+
+ private class ToggleButton
+ {
+ public readonly Direction dir;
+ public readonly GUIButton toggleButton;
+
+ public float OpenState { get; private set; } = 1;
+
+ private bool isHidden;
+ public bool IsHidden
+ {
+ get { return isHidden; }
+ set
+ {
+ isHidden = value;
+ RefreshToggleButtonState();
+ }
+ }
+
+ public ToggleButton(RectTransform rectT, Direction dir)
+ {
+ toggleButton = new GUIButton(rectT, style: "UIToggleButton")
+ {
+ Color = toggleButtonColor,
+ OnClicked = (button, data) =>
+ {
+ IsHidden = !IsHidden;
+ return true;
+ }
+ };
+ this.dir = dir;
+ RefreshToggleButtonState();
+ }
+
+ public void RefreshToggleButtonState()
+ {
+ foreach (GUIComponent child in toggleButton.Children)
+ {
+ switch (dir)
+ {
+ case Direction.Right:
+ child.SpriteEffects = isHidden ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
+ break;
+ case Direction.Left:
+ child.SpriteEffects = isHidden ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
+ break;
+ }
+ }
+ }
+
+ public void UpdateOpenState(float deltaTime, Vector2 hiddenPos, RectTransform panel)
+ {
+ panel.AbsoluteOffset = Vector2.SmoothStep(hiddenPos, Vector2.Zero, OpenState).ToPoint();
+ OpenState = isHidden ? Math.Max(OpenState - deltaTime * 2, 0) : Math.Min(OpenState + deltaTime * 2, 1);
+ }
+ }
+
+ #endregion
+
#region Params
private List AnimParams => character.AnimController.AllAnimParams;
private AnimationParams CurrentAnimation => character.AnimController.CurrentAnimationParams;
@@ -2400,47 +2785,48 @@ namespace Barotrauma
}
else
{
- //if (selectedJoints.Any())
- //{
- // foreach (var jointParams in RagdollParams.Joints)
- // {
- // if (selectedJoints.Any(j => j.jointParams == jointParams))
- // {
- // jointParams?.AddToEditor(ParamsEditor.Instance);
- // }
- // }
- //}
- //if (selectedLimbs.Any())
- //{
- // foreach (var limbParams in RagdollParams.Limbs)
- // {
- // if (limbParams == null) { continue; }
- // var selectedLimb = selectedLimbs.Find(l => l.limbParams == limbParams);
- // if (selectedLimb != null)
- // {
- // limbParams.AddToEditor(ParamsEditor.Instance);
- // if (selectedLimb.attack != null)
- // {
- // var attackEditor = new SerializableEntityEditor(ParamsEditor.Instance.EditorBox.Content.RectTransform, selectedLimb.attack, false, true);
- // }
- // }
- // }
- //}
- foreach (var joint in selectedJoints)
+ if (editRagdoll || !editLimbs && !editJoints)
{
- joint.jointParams.AddToEditor(ParamsEditor.Instance);
+ RagdollParams.AddToEditor(ParamsEditor.Instance, alsoChildren: false);
}
- foreach (var limb in selectedLimbs)
+ if (editJoints)
{
- limb.limbParams.AddToEditor(ParamsEditor.Instance);
- if (limb.attack != null)
+ if (selectedJoints.None())
{
- new SerializableEntityEditor(ParamsEditor.Instance.EditorBox.Content.RectTransform, limb.attack, inGame: false, showName: true);
+ RagdollParams.Joints.ForEach(jp => jp.AddToEditor(ParamsEditor.Instance));
+ }
+ else
+ {
+ foreach (var joint in selectedJoints)
+ {
+ joint.jointParams.AddToEditor(ParamsEditor.Instance);
+ }
}
}
- if (selectedJoints.None() && selectedLimbs.None())
+ if (editLimbs)
{
- RagdollParams.AddToEditor(ParamsEditor.Instance);
+ if (selectedLimbs.None())
+ {
+ foreach (var limb in character.AnimController.Limbs)
+ {
+ limb.limbParams.AddToEditor(ParamsEditor.Instance);
+ if (limb.attack != null)
+ {
+ new SerializableEntityEditor(ParamsEditor.Instance.EditorBox.Content.RectTransform, limb.attack, inGame: false, showName: true);
+ }
+ }
+ }
+ else
+ {
+ foreach (var limb in selectedLimbs)
+ {
+ limb.limbParams.AddToEditor(ParamsEditor.Instance);
+ if (limb.attack != null)
+ {
+ new SerializableEntityEditor(ParamsEditor.Instance.EditorBox.Content.RectTransform, limb.attack, inGame: false, showName: true);
+ }
+ }
+ }
}
}
}
@@ -2540,6 +2926,7 @@ namespace Barotrauma
float closestDistance = float.MaxValue;
foreach (Limb l in character.AnimController.Limbs)
{
+ if (l == null) { continue; }
if (filter == null ? true : filter(l))
{
float distance = Vector2.DistanceSquared(GetLimbSpritesheetRect(l).Center.ToVector2(), targetPos);
@@ -2625,7 +3012,7 @@ namespace Barotrauma
private void DrawJointCreationOnSpritesheet(SpriteBatch spriteBatch, Vector2 startPos)
{
// Spritesheet
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 200, GameMain.GraphicsHeight - 150), GetCharacterEditorTranslation("SelectTargetLimbForJointEnd"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
+ GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 200, GameMain.GraphicsHeight - 200), GetCharacterEditorTranslation("SelectTargetLimbForJointEnd"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
GUI.DrawLine(spriteBatch, startPos, PlayerInput.MousePosition, Color.LightGreen, width: 3);
if (targetLimb != null && targetLimb.ActiveSprite != null)
{
@@ -2636,7 +3023,7 @@ namespace Barotrauma
private void DrawJointCreationOnRagdoll(SpriteBatch spriteBatch, Vector2 startPos)
{
// Ragdoll
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 200, GameMain.GraphicsHeight - 150), GetCharacterEditorTranslation("SelectTargetLimbForJointEnd"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
+ GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 200, GameMain.GraphicsHeight - 200), GetCharacterEditorTranslation("SelectTargetLimbForJointEnd"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
GUI.DrawLine(spriteBatch, startPos, PlayerInput.MousePosition, Color.LightGreen, width: 3);
if (targetLimb != null && targetLimb.ActiveSprite != null)
{
@@ -2663,11 +3050,11 @@ namespace Barotrauma
}
else if (height > width)
{
- spriteSheetMaxZoom = (centerPanel.Rect.Bottom - spriteSheetOffsetY - margin) / height;
+ spriteSheetMaxZoom = (centerArea.Rect.Bottom - spriteSheetOffsetY - margin) / height;
}
else
{
- spriteSheetMaxZoom = (centerPanel.Rect.Left - spriteSheetOffsetX - margin) / width;
+ spriteSheetMaxZoom = (centerArea.Rect.Left - spriteSheetOffsetX - margin) / width;
}
spriteSheetMinZoom = spriteSheetMinZoom > spriteSheetMaxZoom ? spriteSheetMaxZoom : 0.25f;
spriteSheetZoom = MathHelper.Clamp(1, spriteSheetMinZoom, spriteSheetMaxZoom);
@@ -2740,23 +3127,12 @@ namespace Barotrauma
var foot = character.AnimController.GetLimb(LimbType.RightFoot) ?? character.AnimController.GetLimb(LimbType.LeftFoot);
var hand = character.AnimController.GetLimb(LimbType.RightHand) ?? character.AnimController.GetLimb(LimbType.LeftHand);
var arm = character.AnimController.GetLimb(LimbType.RightArm) ?? character.AnimController.GetLimb(LimbType.LeftArm);
- int widgetDefaultSize = 10;
// Note: the main collider rotates only when swimming
float dir = character.AnimController.Dir;
- Vector2 colliderBottom = character.AnimController.GetColliderBottom();
- //Vector2 centerOfMass = character.AnimController.GetCenterOfMass();
- Vector2 simSpaceForward = Vector2.Transform(Vector2.UnitY, Matrix.CreateRotationZ(collider.Rotation));
- //Vector2 simSpaceLeft = Vector2.Transform(-Vector2.UnitX, Matrix.CreateRotationZ(collider.Rotation));
- Vector2 screenSpaceForward = VectorExtensions.BackwardFlipped(collider.Rotation, 1);
- Vector2 screenSpaceLeft = screenSpaceForward.Right();
- // The forward vector is left or right in screen space when the unit is not swimming. Cannot rely on the collider here, because the rotation may vary on ground.
- Vector2 forward = animParams.IsSwimAnimation ? screenSpaceForward : Vector2.UnitX * dir;
Vector2 GetSimSpaceForward() => animParams.IsSwimAnimation ? Vector2.Transform(Vector2.UnitY, Matrix.CreateRotationZ(collider.Rotation)) : Vector2.UnitX * character.AnimController.Dir;
Vector2 GetScreenSpaceForward() => animParams.IsSwimAnimation ? VectorExtensions.BackwardFlipped(collider.Rotation, 1) : Vector2.UnitX * character.AnimController.Dir;
bool ShowCycleWidget() => PlayerInput.KeyDown(Keys.LeftAlt) && (CurrentAnimation is IHumanAnimation || CurrentAnimation is GroundedMovementParams);
-
- bool altDown = PlayerInput.KeyDown(Keys.LeftAlt);
- if (!altDown && (animParams is IHumanAnimation || animParams is GroundedMovementParams))
+ if (!PlayerInput.KeyDown(Keys.LeftAlt) && (animParams is IHumanAnimation || animParams is GroundedMovementParams))
{
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 120, 100), GetCharacterEditorTranslation("HoldLeftAltToAdjustCycleSpeed"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
}
@@ -2887,14 +3263,26 @@ namespace Barotrauma
isDirectionSet = true;
}
var scaledInput = ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed) / Cam.Zoom;
- if (isHorizontal)
+ if (PlayerInput.KeyDown(Keys.LeftAlt))
+ {
+ if (isHorizontal)
+ {
+ TryUpdateAnimParam("headleanamount", humanGroundedParams.HeadLeanAmount + scaledInput.X * character.AnimController.Dir);
+ w.refresh();
+ w.DrawPos = new Vector2(PlayerInput.MousePosition.X, w.DrawPos.Y);
+ }
+ else
+ {
+ TryUpdateAnimParam("headposition", humanGroundedParams.HeadPosition - scaledInput.Y / RagdollParams.JointScale);
+ w.refresh();
+ w.DrawPos = new Vector2(w.DrawPos.X, PlayerInput.MousePosition.Y);
+ }
+ }
+ else
{
TryUpdateAnimParam("headleanamount", humanGroundedParams.HeadLeanAmount + scaledInput.X * character.AnimController.Dir);
w.refresh();
w.DrawPos = new Vector2(PlayerInput.MousePosition.X, w.DrawPos.Y);
- }
- else
- {
TryUpdateAnimParam("headposition", humanGroundedParams.HeadPosition - scaledInput.Y / RagdollParams.JointScale);
w.refresh();
w.DrawPos = new Vector2(w.DrawPos.X, PlayerInput.MousePosition.Y);
@@ -2904,12 +3292,20 @@ namespace Barotrauma
{
if (w.IsControlled && isDirectionSet)
{
- if (isHorizontal)
+ if (PlayerInput.KeyDown(Keys.LeftAlt))
{
- GUI.DrawLine(spriteBatch, new Vector2(0, w.DrawPos.Y), new Vector2(GameMain.GraphicsWidth, w.DrawPos.Y), Color.Red);
+ if (isHorizontal)
+ {
+ GUI.DrawLine(spriteBatch, new Vector2(0, w.DrawPos.Y), new Vector2(GameMain.GraphicsWidth, w.DrawPos.Y), Color.Red);
+ }
+ else
+ {
+ GUI.DrawLine(spriteBatch, new Vector2(w.DrawPos.X, 0), new Vector2(w.DrawPos.X, GameMain.GraphicsHeight), Color.Red);
+ }
}
else
{
+ GUI.DrawLine(spriteBatch, new Vector2(0, w.DrawPos.Y), new Vector2(GameMain.GraphicsWidth, w.DrawPos.Y), Color.Red);
GUI.DrawLine(spriteBatch, new Vector2(w.DrawPos.X, 0), new Vector2(w.DrawPos.X, GameMain.GraphicsHeight), Color.Red);
}
}
@@ -2948,7 +3344,8 @@ namespace Barotrauma
referencePoint = torso.SimPosition;
if (animParams is HumanGroundedParams || animParams is HumanSwimParams)
{
- referencePoint -= simSpaceForward * 0.25f;
+ var f = Vector2.Transform(Vector2.UnitY, Matrix.CreateRotationZ(collider.Rotation));
+ referencePoint -= f * 0.25f;
}
// Torso angle
DrawRadialWidget(spriteBatch, SimToScreen(referencePoint), animParams.TorsoAngle, GetCharacterEditorTranslation("TorsoAngle"), Color.White,
@@ -2975,14 +3372,26 @@ namespace Barotrauma
isDirectionSet = true;
}
var scaledInput = ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed) / Cam.Zoom;
- if (isHorizontal)
+ if (PlayerInput.KeyDown(Keys.LeftAlt))
+ {
+ if (isHorizontal)
+ {
+ TryUpdateAnimParam("torsoleanamount", humanGroundedParams.TorsoLeanAmount + scaledInput.X * character.AnimController.Dir);
+ w.refresh();
+ w.DrawPos = new Vector2(PlayerInput.MousePosition.X, w.DrawPos.Y);
+ }
+ else
+ {
+ TryUpdateAnimParam("torsoposition", humanGroundedParams.TorsoPosition - scaledInput.Y / RagdollParams.JointScale);
+ w.refresh();
+ w.DrawPos = new Vector2(w.DrawPos.X, PlayerInput.MousePosition.Y);
+ }
+ }
+ else
{
TryUpdateAnimParam("torsoleanamount", humanGroundedParams.TorsoLeanAmount + scaledInput.X * character.AnimController.Dir);
w.refresh();
w.DrawPos = new Vector2(PlayerInput.MousePosition.X, w.DrawPos.Y);
- }
- else
- {
TryUpdateAnimParam("torsoposition", humanGroundedParams.TorsoPosition - scaledInput.Y / RagdollParams.JointScale);
w.refresh();
w.DrawPos = new Vector2(w.DrawPos.X, PlayerInput.MousePosition.Y);
@@ -2992,12 +3401,20 @@ namespace Barotrauma
{
if (w.IsControlled && isDirectionSet)
{
- if (isHorizontal)
+ if (PlayerInput.KeyDown(Keys.LeftAlt))
{
- GUI.DrawLine(spriteBatch, new Vector2(0, w.DrawPos.Y), new Vector2(GameMain.GraphicsWidth, w.DrawPos.Y), Color.DarkRed);
+ if (isHorizontal)
+ {
+ GUI.DrawLine(spriteBatch, new Vector2(0, w.DrawPos.Y), new Vector2(GameMain.GraphicsWidth, w.DrawPos.Y), Color.DarkRed);
+ }
+ else
+ {
+ GUI.DrawLine(spriteBatch, new Vector2(w.DrawPos.X, 0), new Vector2(w.DrawPos.X, GameMain.GraphicsHeight), Color.DarkRed);
+ }
}
else
{
+ GUI.DrawLine(spriteBatch, new Vector2(0, w.DrawPos.Y), new Vector2(GameMain.GraphicsWidth, w.DrawPos.Y), Color.DarkRed);
GUI.DrawLine(spriteBatch, new Vector2(w.DrawPos.X, 0), new Vector2(w.DrawPos.X, GameMain.GraphicsHeight), Color.DarkRed);
}
}
@@ -3042,6 +3459,7 @@ namespace Barotrauma
{
if (fishParams != null)
{
+ Vector2 colliderBottom = character.AnimController.GetColliderBottom();
foreach (Limb limb in character.AnimController.Limbs)
{
if (limb.type != LimbType.LeftFoot && limb.type != LimbType.RightFoot) continue;
@@ -3359,7 +3777,7 @@ namespace Barotrauma
bool altDown = PlayerInput.KeyDown(Keys.LeftAlt);
if (!altDown && editJoints && selectedJoints.Any())
{
- GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 200, 100), GetCharacterEditorTranslation("HoldLeftAltToManipulateJoint"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
+ GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 200, 250), GetCharacterEditorTranslation("HoldLeftAltToManipulateJoint"), Color.White, Color.Black * 0.5f, 10, GUI.Font);
}
foreach (Limb limb in character.AnimController.Limbs)
{
@@ -3407,7 +3825,7 @@ namespace Barotrauma
var f = Vector2.Transform(jointPos, Matrix.CreateRotationZ(limb.Rotation));
f.Y = -f.Y;
Vector2 tformedJointPos = limbScreenPos + f * Cam.Zoom;
- if (showRagdoll)
+ if (editRagdoll)
{
ShapeExtensions.DrawPoint(spriteBatch, limbScreenPos, Color.Black, size: 5);
ShapeExtensions.DrawPoint(spriteBatch, limbScreenPos, Color.White, size: 1);
@@ -3684,7 +4102,6 @@ namespace Barotrauma
color: Color.White,
layerDepth: 0);
}
- GUI.DrawRectangle(spriteBatch, rect, selectedLimbs.Contains(limb) ? Color.Yellow : Color.Red);
// The origin is manipulated when the character is flipped. We have to undo it here.
if (character.AnimController.Dir < 0)
{
@@ -3696,6 +4113,7 @@ namespace Barotrauma
}
if (editLimbs)
{
+ GUI.DrawRectangle(spriteBatch, rect, selectedLimbs.Contains(limb) ? Color.Yellow : Color.Red);
int widgetSize = 8;
int halfSize = widgetSize / 2;
Vector2 stringOffset = new Vector2(5, 14);
@@ -4370,6 +4788,7 @@ namespace Barotrauma
private bool canEnterSubmarine = true;
private string texturePath;
private string xmlPath;
+ private ContentPackage contentPackage;
private Dictionary limbXElements = new Dictionary();
private List limbGUIElements = new List();
private List jointXElements = new List();
@@ -4388,6 +4807,13 @@ namespace Barotrauma
}
}
+ public void Reset()
+ {
+ CharacterView.Get().Release();
+ RagdollView.Get().Release();
+ instance = null;
+ }
+
public enum Tab { None, Character, Ragdoll }
private View activeView;
private Tab currentTab;
@@ -4406,7 +4832,7 @@ namespace Barotrauma
break;
case Tab.None:
default:
- instance = null;
+ Reset();
break;
}
}
@@ -4419,28 +4845,37 @@ namespace Barotrauma
private class CharacterView : View
{
private static CharacterView instance;
- public static CharacterView Get() => Get(instance);
+ public static CharacterView Get() => Get(ref instance);
+
+ public override void Release() => instance = null;
protected override GUIMessageBox Create()
{
var box = new GUIMessageBox(GetCharacterEditorTranslation("CreateNewCharacter"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Next") }, new Vector2(0.5f, 1.0f));
+ box.Header.Font = GUI.LargeFont;
box.Content.ChildAnchor = Anchor.TopCenter;
box.Content.AbsoluteSpacing = 20;
int elementSize = 30;
var listBox = new GUIListBox(new RectTransform(new Vector2(1, 0.9f), box.Content.RectTransform));
- var topGroup = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, elementSize * 6 + 20), listBox.Content.RectTransform)) { AbsoluteSpacing = 2 };
+ var topGroup = new GUILayoutGroup(new RectTransform(Vector2.One, listBox.Content.RectTransform)) { AbsoluteSpacing = 2 };
var fields = new List();
GUITextBox texturePathElement = null;
GUITextBox xmlPathElement = null;
+ GUIDropDown contentPackageDropDown = null;
+ bool updateTexturePath = true;
void UpdatePaths()
{
- string pathBase = $"Mods/Characters/{Name}/{Name}";
+ string pathBase = ContentPackage == GameMain.VanillaContent ? $"Content/Characters/{Name}/{Name}"
+ : $"Mods/{(ContentPackage != null ? ContentPackage.Name + "/" : string.Empty)}Characters/{Name}/{Name}";
XMLPath = $"{pathBase}.xml";
- TexturePath = $"{pathBase}.png";
- texturePathElement.Text = TexturePath;
xmlPathElement.Text = XMLPath;
+ if (updateTexturePath)
+ {
+ TexturePath = $"{pathBase}.png";
+ texturePathElement.Text = TexturePath;
+ }
}
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < 6; i++)
{
var mainElement = new GUIFrame(new RectTransform(new Point(topGroup.RectTransform.Rect.Width, elementSize), topGroup.RectTransform), style: null, color: Color.Gray * 0.25f);
fields.Add(mainElement);
@@ -4500,10 +4935,77 @@ namespace Barotrauma
};
texturePathElement.OnTextChanged += (tb, text) =>
{
+ updateTexturePath = false;
TexturePath = text;
return true;
};
break;
+ case 5:
+ mainElement.RectTransform.NonScaledSize = new Point(
+ mainElement.RectTransform.NonScaledSize.X,
+ mainElement.RectTransform.NonScaledSize.Y * 2);
+ new GUITextBlock(leftElement, TextManager.Get("ContentPackage"));
+ var rightContainer = new GUIFrame(rightElement, style: null);
+ contentPackageDropDown = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.5f), rightContainer.RectTransform, Anchor.TopRight));
+ foreach (ContentPackage cp in ContentPackage.List)
+ {
+#if !DEBUG
+ if (cp == GameMain.VanillaContent) { continue; }
+#endif
+ contentPackageDropDown.AddItem(cp.Name, userData: cp, toolTip: cp.Path);
+ }
+ contentPackageDropDown.OnSelected = (obj, userdata) =>
+ {
+ ContentPackage = userdata as ContentPackage;
+ updateTexturePath = true;
+ UpdatePaths();
+ return true;
+ };
+ var contentPackageNameElement = new GUITextBox(new RectTransform(new Vector2(0.7f, 0.5f), rightContainer.RectTransform, Anchor.BottomLeft),
+ TextManager.Get("name"))
+ {
+ CaretColor = Color.White,
+ };
+ var createNewPackageButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.5f), rightContainer.RectTransform, Anchor.BottomRight), TextManager.Get("CreateNew"))
+ {
+ OnClicked = (btn, userdata) =>
+ {
+ if (string.IsNullOrEmpty(contentPackageNameElement.Text))
+ {
+ contentPackageNameElement.Flash();
+ return false;
+ }
+ if (ContentPackage.List.Any(cp => cp.Name.ToLower() == contentPackageNameElement.Text.ToLower()))
+ {
+ new GUIMessageBox("", TextManager.Get("charactereditor.contentpackagenameinuse", fallBackTag: "leveleditorlevelobjnametaken"));
+ return false;
+ }
+ string fileName = ToolBox.RemoveInvalidFileNameChars(contentPackageNameElement.Text);
+ ContentPackage = ContentPackage.CreatePackage(
+ contentPackageNameElement.Text,
+ Path.Combine(ContentPackage.Folder, $"{fileName}.xml"), false);
+ ContentPackage.List.Add(ContentPackage);
+ GameMain.Config.SelectedContentPackages.Add(ContentPackage);
+ contentPackageDropDown.AddItem(ContentPackage.Name, ContentPackage, ContentPackage.Path);
+ contentPackageDropDown.SelectItem(ContentPackage);
+ contentPackageNameElement.Text = "";
+ return true;
+ },
+ Enabled = false
+ };
+ Color textColor = contentPackageNameElement.TextColor;
+ contentPackageNameElement.TextColor *= 0.6f;
+ contentPackageNameElement.OnSelected += (sender, key) =>
+ {
+ contentPackageNameElement.Text = "";
+ };
+ contentPackageNameElement.OnTextChanged += (textBox, text) =>
+ {
+ textBox.TextColor = textColor;
+ createNewPackageButton.Enabled = !string.IsNullOrWhiteSpace(text);
+ return true;
+ };
+ break;
}
}
UpdatePaths();
@@ -4519,12 +5021,24 @@ namespace Barotrauma
// Next
box.Buttons[1].OnClicked += (b, d) =>
{
+ if (ContentPackage == null)
+ {
+ contentPackageDropDown.Flash();
+ return false;
+ }
if (!File.Exists(TexturePath))
{
GUI.AddMessage(GetCharacterEditorTranslation("TextureDoesNotExist"), Color.Red);
texturePathElement.Flash(Color.Red);
return false;
}
+ var path = Path.GetFileName(TexturePath);
+ if (!path.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase))
+ {
+ GUI.AddMessage(TextManager.Get("WrongFileType"), Color.Red);
+ texturePathElement.Flash(Color.Red);
+ return false;
+ }
Wizard.Instance.SelectTab(Tab.Ragdoll);
return true;
};
@@ -4535,11 +5049,14 @@ namespace Barotrauma
private class RagdollView : View
{
private static RagdollView instance;
- public static RagdollView Get() => Get(instance);
+ public static RagdollView Get() => Get(ref instance);
+
+ public override void Release() => instance = null;
protected override GUIMessageBox Create()
{
var box = new GUIMessageBox(GetCharacterEditorTranslation("DefineRagdoll"), string.Empty, new string[] { TextManager.Get("Previous"), TextManager.Get("Create") }, new Vector2(0.5f, 1.0f));
+ box.Header.Font = GUI.LargeFont;
box.Content.ChildAnchor = Anchor.TopCenter;
box.Content.AbsoluteSpacing = 20;
int elementSize = 30;
@@ -4551,10 +5068,11 @@ namespace Barotrauma
// Limbs
var limbsElement = new GUIFrame(new RectTransform(new Vector2(1, 0.05f), bottomGroup.RectTransform), style: null) { CanBeFocused = false };
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), limbsElement.RectTransform), $"{GetCharacterEditorTranslation("Limbs")}: ");
- var limbButtonElement = new GUIFrame(new RectTransform(new Vector2(0.5f, 1f), limbsElement.RectTransform)
- { RelativeOffset = new Vector2(0.25f, 0) }, style: null) { CanBeFocused = false };
+ var limbButtonElement = new GUIFrame(new RectTransform(new Vector2(0.8f, 1f), limbsElement.RectTransform)
+ { RelativeOffset = new Vector2(0.1f, 0) }, style: null) { CanBeFocused = false };
+ var limbEditLayout = new GUILayoutGroup(new RectTransform(Vector2.One, limbButtonElement.RectTransform), isHorizontal: true) { AbsoluteSpacing = 10 };
var limbsList = new GUIListBox(new RectTransform(new Vector2(1, 0.45f), bottomGroup.RectTransform));
- var removeLimbButton = new GUIButton(new RectTransform(new Point(limbButtonElement.Rect.Height, limbButtonElement.Rect.Height), limbButtonElement.RectTransform), "-")
+ var removeLimbButton = new GUIButton(new RectTransform(new Point(limbButtonElement.Rect.Height, limbButtonElement.Rect.Height), limbEditLayout.RectTransform), "-")
{
OnClicked = (b, d) =>
{
@@ -4565,10 +5083,7 @@ namespace Barotrauma
return true;
}
};
- var addLimbButton = new GUIButton(new RectTransform(new Point(limbButtonElement.Rect.Height, limbButtonElement.Rect.Height), limbButtonElement.RectTransform)
- {
- AbsoluteOffset = new Point(removeLimbButton.Rect.Width + 10, 0)
- }, "+")
+ var addLimbButton = new GUIButton(new RectTransform(new Point(limbButtonElement.Rect.Height, limbButtonElement.Rect.Height), limbEditLayout.RectTransform), "+")
{
OnClicked = (b, d) =>
{
@@ -4576,22 +5091,101 @@ namespace Barotrauma
switch (LimbGUIElements.Count)
{
case 0:
- limbType = LimbType.Head;
+ limbType = LimbType.Torso;
break;
case 1:
- limbType = LimbType.Torso;
+ limbType = LimbType.Head;
break;
}
CreateLimbGUIElement(limbsList.Content.RectTransform, elementSize, id: LimbGUIElements.Count, limbType: limbType);
return true;
}
};
+
+ int x = 1, y = 1, w = 100, h = 100;
+ int otherElements = limbButtonElement.Rect.Width / 4 + 10 + limbButtonElement.Rect.Height * 2 + 10 + limbButtonElement.RectTransform.AbsoluteOffset.X;
+ var frame = new GUIFrame(new RectTransform(new Point(limbEditLayout.Rect.Width - otherElements, limbButtonElement.Rect.Height), limbEditLayout.RectTransform), color: Color.Transparent);
+ var inputArea = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform, Anchor.TopRight), isHorizontal: true, childAnchor: Anchor.CenterRight)
+ {
+ Stretch = true,
+ RelativeSpacing = 0.01f
+ };
+ for (int i = 3; i >= 0; i--)
+ {
+ var element = new GUIFrame(new RectTransform(new Vector2(0.22f, 1), inputArea.RectTransform) { MinSize = new Point(50, 0), MaxSize = new Point(150, 50) }, style: null);
+ new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform, Anchor.CenterLeft), GUI.rectComponentLabels[i], font: GUI.SmallFont, textAlignment: Alignment.CenterLeft);
+ GUINumberInput numberInput = new GUINumberInput(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.CenterRight), GUINumberInput.NumberType.Int)
+ {
+ Font = GUI.SmallFont
+ };
+ switch (i)
+ {
+ case 0:
+ case 1:
+ numberInput.IntValue = 1;
+ numberInput.MinValueInt = 1;
+ numberInput.MaxValueInt = 100;
+ break;
+ case 2:
+ case 3:
+ numberInput.IntValue = 100;
+ numberInput.MinValueInt = 0;
+ numberInput.MaxValueInt = 999;
+ break;
+
+ }
+ int comp = i;
+ numberInput.OnValueChanged += (numInput) =>
+ {
+ switch (comp)
+ {
+ case 0:
+ x = numInput.IntValue;
+ break;
+ case 1:
+ y = numInput.IntValue;
+ break;
+ case 2:
+ w = numInput.IntValue;
+ break;
+ case 3:
+ h = numInput.IntValue;
+ break;
+ }
+ };
+ }
+
+ new GUIButton(new RectTransform(new Point(limbButtonElement.Rect.Width / 4, limbButtonElement.Rect.Height), limbEditLayout.RectTransform)
+ , GetCharacterEditorTranslation("AddMultipleLimbsButton"))
+ {
+ OnClicked = (b, d) =>
+ {
+ for (int i = 0; i < x; i++)
+ {
+ for (int j = 0; j < y; j++)
+ {
+ LimbType limbType = LimbType.None;
+ switch (LimbGUIElements.Count)
+ {
+ case 0:
+ limbType = LimbType.Torso;
+ break;
+ case 1:
+ limbType = LimbType.Head;
+ break;
+ }
+ CreateLimbGUIElement(limbsList.Content.RectTransform, elementSize, id: LimbGUIElements.Count, limbType: limbType, sourceRect: new Rectangle(i * w, j * h, w, h));
+ }
+ }
+ return true;
+ }
+ };
// Joints
new GUIFrame(new RectTransform(new Vector2(1, 0.05f), bottomGroup.RectTransform), style: null) { CanBeFocused = false };
var jointsElement = new GUIFrame(new RectTransform(new Vector2(1, 0.05f), bottomGroup.RectTransform), style: null) { CanBeFocused = false };
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), jointsElement.RectTransform), $"{GetCharacterEditorTranslation("Joints")}: ");
var jointButtonElement = new GUIFrame(new RectTransform(new Vector2(0.5f, 1f), jointsElement.RectTransform)
- { RelativeOffset = new Vector2(0.25f, 0) }, style: null) { CanBeFocused = false };
+ { RelativeOffset = new Vector2(0.1f, 0) }, style: null) { CanBeFocused = false };
var jointsList = new GUIListBox(new RectTransform(new Vector2(1, 0.45f), bottomGroup.RectTransform));
var removeJointButton = new GUIButton(new RectTransform(new Point(jointButtonElement.Rect.Height, jointButtonElement.Rect.Height), jointButtonElement.RectTransform), "-")
{
@@ -4620,6 +5214,7 @@ namespace Barotrauma
if (htmlBox == null)
{
htmlBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadHTML"), string.Empty, new string[] { TextManager.Get("Close"), TextManager.Get("Load") }, new Vector2(0.5f, 1.0f));
+ htmlBox.Header.Font = GUI.LargeFont;
var element = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.05f), htmlBox.Content.RectTransform), style: null, color: Color.Gray * 0.25f);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1), element.RectTransform), GetCharacterEditorTranslation("HTMLPath"));
var htmlPathElement = new GUITextBox(new RectTransform(new Vector2(0.5f, 1), element.RectTransform, Anchor.TopRight), $"Content/Characters/{Name}/{Name}.html");
@@ -4674,7 +5269,7 @@ namespace Barotrauma
{
ParseLimbsFromGUIElements();
ParseJointsFromGUIElements();
- var torsoAttributes = LimbXElements.Values.Select(x => x.Attribute("type")).Where(a => a.Value.ToLowerInvariant() == "torso");
+ var torsoAttributes = LimbXElements.Values.Select(xe => xe.Attribute("type")).Where(a => a.Value.ToLowerInvariant() == "torso");
if (torsoAttributes.Count() != 1)
{
GUI.AddMessage(GetCharacterEditorTranslation("MultipleTorsosDefined"), Color.Red);
@@ -4753,7 +5348,7 @@ namespace Barotrauma
LimbXElements.Values,
JointXElements
};
- if (CharacterEditorScreen.instance.CreateCharacter(Name, Path.GetDirectoryName(XMLPath), IsHumanoid, ragdollParams))
+ if (CharacterEditorScreen.instance.CreateCharacter(Name, Path.GetDirectoryName(XMLPath), IsHumanoid, ContentPackage, ragdollParams))
{
GUI.AddMessage(GetCharacterEditorTranslation("CharacterCreated").Replace("[name]", Name), Color.Green, font: GUI.Font);
}
@@ -4774,7 +5369,7 @@ namespace Barotrauma
var idField = new GUIFrame(new RectTransform(new Point(group.Rect.Width, elementSize), group.RectTransform), style: null);
var nameField = new GUIFrame(new RectTransform(new Point(group.Rect.Width, elementSize), group.RectTransform), style: null);
var limbTypeField = GUI.CreateEnumField(limbType, elementSize, GetCharacterEditorTranslation("LimbType"), group.RectTransform, font: GUI.Font);
- var sourceRectField = GUI.CreateRectangleField(sourceRect ?? new Rectangle(0, 0, 2, 2), elementSize, GetCharacterEditorTranslation("SourceRectangle"), group.RectTransform, font: GUI.Font);
+ var sourceRectField = GUI.CreateRectangleField(sourceRect ?? new Rectangle(0, 100 * LimbGUIElements.Count, 100, 100), elementSize, GetCharacterEditorTranslation("SourceRectangle"), group.RectTransform, font: GUI.Font);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1), idField.RectTransform, Anchor.TopLeft), GetCharacterEditorTranslation("ID"));
new GUINumberInput(new RectTransform(new Vector2(0.5f, 1), idField.RectTransform, Anchor.TopRight), GUINumberInput.NumberType.Int)
{
@@ -4867,6 +5462,11 @@ namespace Barotrauma
get => Instance.canEnterSubmarine;
set => Instance.canEnterSubmarine = value;
}
+ public ContentPackage ContentPackage
+ {
+ get => Instance.contentPackage;
+ set => Instance.contentPackage = value;
+ }
public string TexturePath
{
get => Instance.texturePath;
@@ -4912,7 +5512,7 @@ namespace Barotrauma
}
protected abstract GUIMessageBox Create();
- protected static T Get(T instance) where T : View, new()
+ protected static T Get(ref T instance) where T : View, new()
{
if (instance == null)
{
@@ -4921,6 +5521,8 @@ namespace Barotrauma
return instance;
}
+ public abstract void Release();
+
protected void ParseLimbsFromGUIElements()
{
LimbXElements.Clear();
@@ -5073,10 +5675,8 @@ namespace Barotrauma
{
if (hierarchy != "0")
{
- // OLD LOGIC: If the bone is at the root hierarchy, parent the bone to the last sibling (1 is parented to 0, 2 to 1 etc)
// NEW LOGIC: if hierarchy length == 1, parent to 0
// Else parent to the last bone in the current hierarchy (11 is parented to 1, 212 is parented to 21 etc)
- //string parent = hierarchy.Length > 1 ? hierarchy.Remove(hierarchy.Length - 1, 1) : (int.Parse(hierarchy) - 1).ToString();
string parent = hierarchy.Length > 1 ? hierarchy.Remove(hierarchy.Length - 1, 1) : "0";
if (hierarchyToID.TryGetValue(parent, out int parentID))
{
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs
index 15874f04f..62b74fa4b 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs
@@ -9,6 +9,7 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
+using System.Xml.Linq;
namespace Barotrauma
{
@@ -736,6 +737,7 @@ namespace Barotrauma
string arguments = "-name \"" + name.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" +
" -port " + port.ToString() +
" -queryport " + queryPort.ToString() +
+ " -public " + isPublicBox.Selected.ToString() +
" -password \"" + passwordBox.Text.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"" +
" -upnp " + useUpnpBox.Selected +
" -maxplayers " + maxPlayersBox.Text +
@@ -940,6 +942,20 @@ namespace Barotrauma
#region UI Methods
private void CreateHostServerFields()
{
+ int port = NetConfig.DefaultPort;
+ int queryPort = NetConfig.DefaultQueryPort;
+ int maxPlayers = 8;
+ if (File.Exists(ServerSettings.SettingsFile))
+ {
+ XDocument settingsDoc = XMLExtensions.TryLoadXml(ServerSettings.SettingsFile);
+ if (settingsDoc?.Root != null)
+ {
+ port = settingsDoc.Root.GetAttributeInt("port", port);
+ queryPort = settingsDoc.Root.GetAttributeInt("queryport", queryPort);
+ maxPlayers = settingsDoc.Root.GetAttributeInt("maxplayers", maxPlayers);
+ }
+ }
+
Vector2 textLabelSize = new Vector2(1.0f, 0.1f);
Alignment textAlignment = Alignment.CenterLeft;
Vector2 textFieldSize = new Vector2(0.5f, 1.0f);
@@ -954,12 +970,16 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("HostServerButton"), textAlignment: Alignment.Center, font: GUI.LargeFont) { ForceUpperCase = true };
var label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerName"), textAlignment: textAlignment);
- serverNameBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment);
+ serverNameBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment)
+ {
+ MaxTextLength = NetConfig.ServerNameMaxLength,
+ OverflowClip = true
+ };
label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerPort"), textAlignment: textAlignment);
portBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment)
{
- Text = NetConfig.DefaultPort.ToString(),
+ Text = port.ToString(),
ToolTip = TextManager.Get("ServerPortToolTip")
};
@@ -968,7 +988,7 @@ namespace Barotrauma
label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerQueryPort"), textAlignment: textAlignment);
queryPortBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), textAlignment: textAlignment)
{
- Text = NetConfig.DefaultQueryPort.ToString(),
+ Text = queryPort.ToString(),
ToolTip = TextManager.Get("ServerQueryPortToolTip")
};
}
@@ -987,7 +1007,7 @@ namespace Barotrauma
maxPlayersBox = new GUITextBox(new RectTransform(new Vector2(0.6f, 1.0f), buttonContainer.RectTransform), textAlignment: Alignment.Center)
{
- Text = "8",
+ Text = maxPlayers.ToString(),
Enabled = false
};
new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonContainer.RectTransform), "+", textAlignment: Alignment.Center)
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
index c989c73cf..038ee390d 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs
@@ -335,8 +335,12 @@ namespace Barotrauma
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.03f), rightInfoColumn.RectTransform), style: null);
//server info ------------------------------------------------------------------
-
- ServerName = new GUITextBox(new RectTransform(new Vector2(0.3f, 0.05f), infoFrameContent.RectTransform));
+
+ ServerName = new GUITextBox(new RectTransform(new Vector2(infoColumnContainer.RectTransform.RelativeSize.X, 0.05f), infoFrameContent.RectTransform))
+ {
+ MaxTextLength = NetConfig.ServerNameMaxLength,
+ OverflowClip = true
+ };
ServerName.OnDeselected += (textBox, key) =>
{
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Name);
@@ -1608,13 +1612,13 @@ namespace Barotrauma
public void BanPlayer(Client client)
{
if (GameMain.NetworkMember == null || client == null) { return; }
- GameMain.Client.CreateKickReasonPrompt(client.Name, true);
+ GameMain.Client.CreateKickReasonPrompt(client.Name, ban: true, rangeBan: false);
}
public void BanPlayerRange(Client client)
{
if (GameMain.NetworkMember == null || client == null) { return; }
- GameMain.Client.CreateKickReasonPrompt(client.Name, true, true);
+ GameMain.Client.CreateKickReasonPrompt(client.Name, ban: true, rangeBan: true);
}
public override void AddToGUIUpdateList()
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/OldCharacterEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/OldCharacterEditorScreen.cs
deleted file mode 100644
index 26e813e63..000000000
--- a/Barotrauma/BarotraumaClient/Source/Screens/OldCharacterEditorScreen.cs
+++ /dev/null
@@ -1,333 +0,0 @@
-using FarseerPhysics;
-using FarseerPhysics.Dynamics.Joints;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Barotrauma
-{
- class OldCharacterEditorScreen : Screen
- {
- private Camera cam;
-
- private GUIComponent GUIpanel;
- private GUIButton physicsButton;
-
- private GUIListBox limbList, jointList;
-
- private GUIFrame limbPanel;
-
- private Character editingCharacter;
- private Limb editingLimb;
-
- private List textures;
- private List texturePaths;
-
- private bool physicsEnabled;
-
- public override Camera Cam
- {
- get { return cam; }
- }
-
- public override void Select()
- {
- base.Select();
-
- GameMain.DebugDraw = true;
-
- cam = new Camera();
-
- /*GUIpanel = new GUIFrame(new Rectangle(0, 0, 300, GameMain.GraphicsHeight), "");
- //GUIpanel.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
-
- physicsButton = new GUIButton(new Rectangle(0, 50, 200, 25), "Physics", Alignment.Left, "", GUIpanel);
- physicsButton.OnClicked += TogglePhysics;
-
- new GUITextBlock(new Rectangle(0, 80, 0, 25), "Limbs:", "", GUIpanel);
- limbList = new GUIListBox(new Rectangle(0, 110, 0, 250), Color.White * 0.7f, "", GUIpanel);
- limbList.OnSelected = SelectLimb;
-
- new GUITextBlock(new Rectangle(0, 360, 0, 25), "Joints:", "", GUIpanel);
- jointList = new GUIListBox(new Rectangle(0, 390, 0, 250), Color.White * 0.7f, "", GUIpanel);*/
-
- while (Character.CharacterList.Count > 1)
- {
- Character.CharacterList.First().Remove();
- }
-
- if (Character.CharacterList.Count == 1)
- {
- if (editingCharacter != Character.CharacterList[0]) UpdateLimbLists(Character.CharacterList[0]);
- editingCharacter = Character.CharacterList[0];
-
- Vector2 camPos = editingCharacter.AnimController.Limbs[0].body.SimPosition;
- camPos = ConvertUnits.ToDisplayUnits(camPos);
- camPos.Y = -camPos.Y;
- cam.TargetPos = camPos;
-
- if (physicsEnabled)
- {
- editingCharacter.Control(1.0f, cam);
- }
- else
- {
- cam.TargetPos = Vector2.Zero;
- }
- }
-
- textures = new List();
- texturePaths = new List();
- foreach (Limb limb in editingCharacter.AnimController.Limbs)
- {
- if (limb.ActiveSprite==null || texturePaths.Contains(limb.ActiveSprite.FilePath)) continue;
- textures.Add(limb.ActiveSprite.Texture);
- texturePaths.Add(limb.ActiveSprite.FilePath);
- }
- }
-
- ///
- /// Allows the game to run logic such as updating the world,
- /// checking for collisions, gathering input, and playing audio.
- ///
- public override void Update(double deltaTime)
- {
- cam.MoveCamera((float)deltaTime);
-
- GUIpanel.UpdateManually((float)deltaTime);
-
- if (physicsEnabled)
- {
- Character.UpdateAnimAll((float)deltaTime);
-
- Ragdoll.UpdateAll((float)deltaTime, cam);
-
- GameMain.World.Step((float)deltaTime);
- }
- }
-
- public override void AddToGUIUpdateList()
- {
- GUIpanel.AddToGUIUpdateList();
- }
-
- ///
- /// This is called when the game should draw itself.
- ///
- public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
- {
- //cam.UpdateTransform();
-
- graphics.Clear(Color.CornflowerBlue);
-
- spriteBatch.Begin(SpriteSortMode.BackToFront,
- BlendState.AlphaBlend,
- null, null, null, null,
- cam.Transform);
-
- Submarine.Draw(spriteBatch, true);
-
- spriteBatch.End();
-
- spriteBatch.Begin(SpriteSortMode.BackToFront,
- BlendState.AlphaBlend,
- null, null, null, null,
- cam.Transform);
-
- //if (EntityPrefab.Selected != null) EntityPrefab.Selected.UpdatePlacing(spriteBatch, cam);
-
- //Entity.DrawSelecting(spriteBatch, cam);
-
- if (editingCharacter!=null)
- editingCharacter.Draw(spriteBatch, Cam);
-
- spriteBatch.End();
-
- //-------------------- HUD -----------------------------
-
- spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
-
- GUIpanel.DrawManually(spriteBatch);
-
- EditLimb(spriteBatch);
-
-
- int y = 0;
- for (int i = 0; i < textures.Count; i++ )
- {
- int x = GameMain.GraphicsWidth - textures[i].Width;
- spriteBatch.Draw(textures[i], new Vector2(x, y), Color.White);
-
- foreach (Limb limb in editingCharacter.AnimController.Limbs)
- {
- if (limb.ActiveSprite == null || limb.ActiveSprite.FilePath != texturePaths[i]) continue;
- Rectangle rect = limb.ActiveSprite.SourceRect;
- rect.X += x;
- rect.Y += y;
-
- GUI.DrawRectangle(spriteBatch, rect, Color.Red);
-
- Vector2 limbBodyPos = new Vector2(
- rect.X + limb.ActiveSprite.Origin.X,
- rect.Y + limb.ActiveSprite.Origin.Y);
-
- DrawJoints(spriteBatch, limb, limbBodyPos);
-
- //if (limb.BodyShapeTexture == null) continue;
-
- //spriteBatch.Draw(limb.BodyShapeTexture, limbBodyPos,
- // null, Color.White, 0.0f,
- // new Vector2(limb.BodyShapeTexture.Width, limb.BodyShapeTexture.Height) / 2,
- // 1.0f, SpriteEffects.None, 0.0f);
-
- GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitY * 5.0f, limbBodyPos - Vector2.UnitY * 5.0f, Color.White);
- GUI.DrawLine(spriteBatch, limbBodyPos + Vector2.UnitX * 5.0f, limbBodyPos - Vector2.UnitX * 5.0f, Color.White);
-
- if (Vector2.Distance(PlayerInput.MousePosition, limbBodyPos)<5.0f && PlayerInput.LeftButtonHeld())
- {
- limb.ActiveSprite.Origin += PlayerInput.MouseSpeed;
- }
- }
-
- y += textures[i].Height;
- }
-
-
- GUI.Draw(Cam, spriteBatch);
-
- //EntityPrefab.DrawList(spriteBatch, new Vector2(20,50));
-
- //Entity.Edit(spriteBatch, cam);
-
- spriteBatch.End();
- }
-
- private void UpdateLimbLists(Character character)
- {
- limbList.ClearChildren();
- /*foreach (Limb limb in character.AnimController.Limbs)
- {
- GUITextBlock textBlock = new GUITextBlock(
- new Rectangle(0,0,0,25),
- limb.type.ToString(),
- Color.Transparent,
- Color.White,
- Alignment.Left, null,
- limbList);
- textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
- textBlock.UserData = limb;
- }
-
- jointList.ClearChildren();
- foreach (RevoluteJoint joint in character.AnimController.LimbJoints)
- {
- Limb limb1 = (Limb)(joint.BodyA.UserData);
- Limb limb2 = (Limb)(joint.BodyB.UserData);
-
- GUITextBlock textBlock = new GUITextBlock(
- new Rectangle(0, 0, 0, 25),
- limb1.type.ToString() + " - " + limb2.type.ToString(),
- Color.Transparent,
- Color.White,
- Alignment.Left, null,
- jointList);
- textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f);
- textBlock.UserData = joint;
- }*/
- }
-
- private void DrawJoints(SpriteBatch spriteBatch, Limb limb, Vector2 limbBodyPos)
- {
- foreach (var joint in editingCharacter.AnimController.LimbJoints)
- {
- Vector2 jointPos = Vector2.Zero;
-
- if (joint.BodyA == limb.body.FarseerBody)
- {
- jointPos = ConvertUnits.ToDisplayUnits(joint.LocalAnchorA);
-
- }
- else if (joint.BodyB == limb.body.FarseerBody)
- {
- jointPos = ConvertUnits.ToDisplayUnits(joint.LocalAnchorB);
- }
- else
- {
- continue;
- }
-
- Vector2 tformedJointPos = jointPos /= limb.Scale;
- tformedJointPos.Y = -tformedJointPos.Y;
- tformedJointPos += limbBodyPos;
-
- if (joint.BodyA == limb.body.FarseerBody)
- {
- float a1 = joint.UpperLimit - MathHelper.PiOver2;
- float a2 = joint.LowerLimit - MathHelper.PiOver2;
- float a3 = (a1 + a2) / 2.0f;
- GUI.DrawLine(spriteBatch, tformedJointPos, tformedJointPos + new Vector2((float)Math.Cos(a1), -(float)Math.Sin(a1)) * 30.0f, Color.Green);
- GUI.DrawLine(spriteBatch, tformedJointPos, tformedJointPos + new Vector2((float)Math.Cos(a2), -(float)Math.Sin(a2)) * 30.0f, Color.DarkGreen);
-
- GUI.DrawLine(spriteBatch, tformedJointPos, tformedJointPos + new Vector2((float)Math.Cos(a3), -(float)Math.Sin(a3)) * 30.0f, Color.LightGray);
- }
-
- GUI.DrawRectangle(spriteBatch, tformedJointPos, new Vector2(5.0f, 5.0f), Color.Red, true);
- if (Vector2.Distance(PlayerInput.MousePosition, tformedJointPos) < 10.0f)
- {
- GUI.DrawString(spriteBatch, tformedJointPos + Vector2.One*10.0f, jointPos.ToString(), Color.White, Color.Black * 0.5f);
- GUI.DrawRectangle(spriteBatch, tformedJointPos - new Vector2(3.0f, 3.0f), new Vector2(11.0f, 11.0f), Color.Red, false);
- if (PlayerInput.LeftButtonHeld())
- {
- Vector2 speed = ConvertUnits.ToSimUnits(PlayerInput.MouseSpeed);
- speed.Y = -speed.Y;
- if (joint.BodyA == limb.body.FarseerBody)
- {
- joint.LocalAnchorA += speed;
- }
- else
- {
- joint.LocalAnchorB += speed;
- }
- }
- }
- }
- }
-
- private bool SelectLimb(GUIComponent component, object selection)
- {
- /*try
- {
- editingLimb = (Limb)selection;
- limbPanel = new GUIFrame(new Rectangle(300, 0, 500, 100), Color.Gray*0.8f);
- //limbPanel.Padding = new Vector4(10.0f,10.0f,10.0f,10.0f);
- new GUITextBlock(new Rectangle(0, 0, 200, 25), editingLimb.type.ToString(), Color.Transparent, Color.Black, Alignment.Left, null, limbPanel);
-
- //spriteOrigin = new GUITextBlock(new Rectangle(0, 25, 200, 25), "Sprite origin: ", Color.White, Color.Black, Alignment.Left, limbPanel);
-
- }
- catch
- {
- return false;
- }*/
- return true;
- }
-
- private void EditLimb(SpriteBatch spriteBatch)
- {
- if (editingLimb == null) return;
-
- limbPanel.DrawManually(spriteBatch);
- }
-
- private bool TogglePhysics(GUIButton button, object selection)
- {
- physicsEnabled = !physicsEnabled;
-
- physicsButton.Text = (physicsEnabled) ? "Disable physics" : "Enable physics";
-
- return false;
- }
- }
-}
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs
index b109e3f51..b0688089c 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/ServerListScreen.cs
@@ -19,73 +19,87 @@ namespace Barotrauma
//how often the client is allowed to refresh servers
private TimeSpan AllowedRefreshInterval = new TimeSpan(0, 0, 3);
- private GUIFrame menu;
+ private readonly GUIFrame menu;
- private GUIListBox serverList;
- private GUIListBox serverPreview;
+ private readonly GUIListBox serverList;
+ private readonly GUIFrame serverPreview;
- private GUIButton joinButton;
+ private readonly GUIButton joinButton;
- private GUITextBox clientNameBox, ipBox;
+ private readonly GUITextBox clientNameBox, ipBox;
private bool masterServerResponded;
private IRestResponse masterServerResponse;
-
- private GUIButton refreshButton;
-
- private float[] columnRelativeWidth;
+
+ private readonly float[] columnRelativeWidth = new float[] { 0.1f, 0.1f, 0.7f, 0.12f, 0.08f, 0.08f };
+ private readonly string[] columnLabel = new string[] { "ServerListCompatible", "ServerListHasPassword", "ServerListName", "ServerListRoundStarted", "ServerListPlayers", "ServerListPing" };
+
+ private readonly GUILayoutGroup labelHolder;
+ private readonly List labelTexts = new List();
//filters
- private GUITextBox searchBox;
- private GUITickBox filterPassword;
- private GUITickBox filterIncompatible;
- private GUITickBox filterFull;
- private GUITickBox filterEmpty;
+ private readonly GUITextBox searchBox;
+ private readonly GUITickBox filterPassword;
+ private readonly GUITickBox filterIncompatible;
+ private readonly GUITickBox filterFull;
+ private readonly GUITickBox filterEmpty;
- //a timer for
+ private string sortedBy;
+
+ private readonly GUIButton serverPreviewToggleButton;
+
+ //a timer for preventing the client from spamming the refresh button faster than AllowedRefreshInterval
private DateTime refreshDisableTimer;
private bool waitingForRefresh;
-
+
public ServerListScreen()
{
GameMain.Instance.OnResolutionChanged += OnResolutionChanged;
- menu = new GUIFrame(new RectTransform(new Vector2(0.7f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
+ menu = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.85f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
- var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.95f), menu.RectTransform, Anchor.Center), isHorizontal: true)
- { Stretch = true, RelativeSpacing = 0.02f };
-
- //-------------------------------------------------------------------------------------
- //left column
- //-------------------------------------------------------------------------------------
-
- var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.25f, 1.0f), paddedFrame.RectTransform, Anchor.CenterLeft)) { Stretch = true, RelativeSpacing = 0.5f };
-
- var infoHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), leftColumn.RectTransform)) { RelativeSpacing = 0.05f };
-
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), infoHolder.RectTransform, Anchor.Center), TextManager.Get("JoinServer"), font: GUI.LargeFont)
+ var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.95f), menu.RectTransform, Anchor.Center))
{
+ RelativeSpacing = 0.02f,
+ Stretch = true
+ };
+
+ //-------------------------------------------------------------------------------------
+ //Top row
+ //-------------------------------------------------------------------------------------
+
+ var topRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedFrame.RectTransform)) { Stretch = true };
+
+ var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.33f), topRow.RectTransform), TextManager.Get("JoinServer"), font: GUI.LargeFont)
+ {
+ Padding = Vector4.Zero,
ForceUpperCase = true,
AutoScale = true
};
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("YourName"));
- clientNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.13f), infoHolder.RectTransform), "")
+ var infoHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.33f), topRow.RectTransform), isHorizontal: true) { RelativeSpacing = 0.05f, Stretch = true };
+
+ var clientNameHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), infoHolder.RectTransform)) { RelativeSpacing = 0.05f };
+
+ new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), clientNameHolder.RectTransform), TextManager.Get("YourName"));
+ clientNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), clientNameHolder.RectTransform), "")
{
Text = GameMain.Config.DefaultPlayerName,
MaxTextLength = Client.MaxNameLength,
OverflowClip = true
};
+
if (string.IsNullOrEmpty(clientNameBox.Text))
{
clientNameBox.Text = SteamManager.GetUsername();
}
- clientNameBox.OnTextChanged += RefreshJoinButtonState;
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoHolder.RectTransform), TextManager.Get("ServerIP"));
- ipBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.13f), infoHolder.RectTransform), "");
- ipBox.OnTextChanged += RefreshJoinButtonState;
- ipBox.OnSelected += (sender, key) =>
+ var ipBoxHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), infoHolder.RectTransform)) { RelativeSpacing = 0.05f };
+
+ new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), ipBoxHolder.RectTransform), TextManager.Get("ServerIP"));
+ ipBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), ipBoxHolder.RectTransform), "");
+ ipBox.OnTextChanged += (textBox, text) => { joinButton.Enabled = !string.IsNullOrEmpty(text); return true; };
+ ipBox.OnSelected += (sender, key) =>
{
if (sender.UserData is ServerInfo)
{
@@ -94,93 +108,357 @@ namespace Barotrauma
}
};
- var filterHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), leftColumn.RectTransform)) { RelativeSpacing = 0.05f };
-
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), filterHolder.RectTransform), TextManager.Get("FilterServers"));
- searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.13f), filterHolder.RectTransform), "");
-
- var tickBoxHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), filterHolder.RectTransform));
-
- searchBox.OnTextChanged += (txtBox, txt) => { FilterServers(); return true; };
- filterPassword = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.27f), tickBoxHolder.RectTransform), TextManager.Get("FilterPassword"));
- filterPassword.OnSelected += (tickBox) => { FilterServers(); return true; };
- filterIncompatible = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.27f), tickBoxHolder.RectTransform), TextManager.Get("FilterIncompatibleServers"));
- filterIncompatible.OnSelected += (tickBox) => { FilterServers(); return true; };
-
- filterFull = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.27f), tickBoxHolder.RectTransform), TextManager.Get("FilterFullServers"));
- filterFull.OnSelected += (tickBox) => { FilterServers(); return true; };
- filterEmpty = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.27f), tickBoxHolder.RectTransform), TextManager.Get("FilterEmptyServers"));
- filterEmpty.OnSelected += (tickBox) => { FilterServers(); return true; };
-
//-------------------------------------------------------------------------------------
- //right column
+ // Bottom row
//-------------------------------------------------------------------------------------
- var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - leftColumn.RectTransform.RelativeSize.X - 0.017f, 1.0f),
+ var bottomRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f - topRow.RectTransform.RelativeSize.Y),
paddedFrame.RectTransform, Anchor.CenterRight))
{
- RelativeSpacing = 0.02f,
Stretch = true
};
- var serverListHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform)) { Stretch = true, RelativeSpacing = 0.02f };
-
- serverList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), serverListHolder.RectTransform, Anchor.Center))
+ var serverListHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), bottomRow.RectTransform), isHorizontal: true)
{
- OnSelected = (btn, obj) => {
- if (obj is ServerInfo)
+ Stretch = true
+ };
+
+ // filters -------------------------------------------
+
+ var filters = new GUIFrame(new RectTransform(new Vector2(0.25f, 1.0f), serverListHolder.RectTransform, Anchor.Center), style: null)
+ {
+ Color = new Color(12, 14, 15, 255) * 0.5f,
+ OutlineColor = Color.Black
+ };
+ var filterToggle = new GUIButton(new RectTransform(new Vector2(0.02f, 1.0f), serverListHolder.RectTransform, Anchor.CenterRight) { MinSize = new Point(20, 0) }, style: "UIToggleButton")
+ {
+ OnClicked = (btn, userdata) =>
+ {
+ filters.RectTransform.RelativeSize = new Vector2(0.25f, 1.0f);
+ filters.Visible = !filters.Visible;
+ filters.IgnoreLayoutGroups = !filters.Visible;
+ serverListHolder.Recalculate();
+ btn.Children.ForEach(c => c.SpriteEffects = !filters.Visible ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
+ return true;
+ }
+ };
+ filterToggle.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally);
+
+ var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.99f), filters.RectTransform, Anchor.Center))
+ {
+ Stretch = true,
+ RelativeSpacing = 0.015f
+ };
+
+ var filterTitle = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), filterContainer.RectTransform), TextManager.Get("FilterServers"), font: GUI.LargeFont)
+ {
+ Padding = Vector4.Zero,
+ AutoScale = true
+ };
+
+ float elementHeight = 0.05f;
+
+ var searchHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, elementHeight), filterContainer.RectTransform), isHorizontal: true) { Stretch = true };
+
+ var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), searchHolder.RectTransform), TextManager.Get("Search") + "...");
+ searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), searchHolder.RectTransform), "");
+ searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
+ searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
+ searchBox.OnTextChanged += (txtBox, txt) => { FilterServers(); return true; };
+
+ var filterHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform)) { RelativeSpacing = 0.005f };
+
+ List filterTextList = new List();
+ filterPassword = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterPassword"))
+ {
+ ToolTip = TextManager.Get("FilterPassword"),
+ OnSelected = (tickBox) => { FilterServers(); return true; }
+ };
+ filterTextList.Add(filterPassword.TextBlock);
+ filterIncompatible = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterIncompatibleServers"))
+ {
+ ToolTip = TextManager.Get("FilterIncompatibleServers"),
+ OnSelected = (tickBox) => { FilterServers(); return true; }
+ };
+ filterTextList.Add(filterIncompatible.TextBlock);
+ filterFull = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterFullServers"))
+ {
+ ToolTip = TextManager.Get("FilterFullServers"),
+ OnSelected = (tickBox) => { FilterServers(); return true; }
+ };
+ filterTextList.Add(filterFull.TextBlock);
+ filterEmpty = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filterHolder.RectTransform), TextManager.Get("FilterEmptyServers"))
+ {
+ ToolTip = TextManager.Get("FilterEmptyServers"),
+ OnSelected = (tickBox) => { FilterServers(); return true; }
+ };
+ filterTextList.Add(filterEmpty.TextBlock);
+
+ filterContainer.RectTransform.SizeChanged += () =>
+ {
+ filterContainer.RectTransform.RecalculateChildren(true, true);
+ filterTextList.ForEach(t => t.Text = t.ToolTip);
+ GUITextBlock.AutoScaleAndNormalize(filterTextList);
+ if (filterTextList[0].TextScale < 0.8f)
+ {
+ filterTextList.ForEach(t => t.TextScale = 1.0f);
+ filterTextList.ForEach(t => t.Text = ToolBox.LimitString(t.Text, t.Font, (int)(filterContainer.Rect.Width * 0.8f)));
+ }
+ };
+
+ // server list ---------------------------------------------------------------------
+
+ var serverListContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), serverListHolder.RectTransform)) { Stretch = true };
+
+ labelHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.99f, 0.05f), serverListContainer.RectTransform) { MinSize = new Point(0, 15) },
+ isHorizontal: true)
+ {
+ Stretch = true
+ };
+
+ for (int i = 0; i < columnRelativeWidth.Length; i++)
+ {
+ var btn = new GUIButton(new RectTransform(new Vector2(columnRelativeWidth[i], 1.0f), labelHolder.RectTransform),
+ text: TextManager.Get(columnLabel[i]), textAlignment: Alignment.Center, style: null)
+ {
+ Color = new Color(12, 14, 15, 255) * 0.5f,
+ HoverColor = new Color(12, 14, 15, 255) * 2.5f,
+ SelectedColor = Color.Gray * 0.7f,
+ PressedColor = Color.Gray * 0.7f,
+ OutlineColor = Color.Black,
+ ToolTip = TextManager.Get(columnLabel[i]),
+ ForceUpperCase = true,
+ UserData = columnLabel[i],
+ OnClicked = SortList
+ };
+ labelTexts.Add(btn.TextBlock);
+
+ new GUIImage(new RectTransform(new Vector2(0.5f, 0.3f), btn.RectTransform, Anchor.BottomCenter, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonVerticalArrow", scaleToFit: true)
+ {
+ CanBeFocused = false,
+ UserData = "arrowup",
+ Visible = false
+ };
+ new GUIImage(new RectTransform(new Vector2(0.5f, 0.3f), btn.RectTransform, Anchor.BottomCenter, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonVerticalArrow", scaleToFit: true)
+ {
+ CanBeFocused = false,
+ UserData = "arrowdown",
+ SpriteEffects = SpriteEffects.FlipVertically,
+ Visible = false
+ };
+ }
+
+ serverList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), serverListContainer.RectTransform, Anchor.Center))
+ {
+ ScrollBarVisible = true,
+ OnSelected = (btn, obj) =>
+ {
+ if (obj is ServerInfo serverInfo)
{
- ServerInfo serverInfo = (ServerInfo)obj;
+ joinButton.Enabled = true;
+ ipBox.UserData = serverInfo;
+ ipBox.Text = serverInfo.ServerName;
+ if (!serverPreview.Visible)
+ {
+ serverPreview.RectTransform.RelativeSize = new Vector2(0.3f, 1.0f);
+ serverPreviewToggleButton.Visible = true;
+ serverPreviewToggleButton.IgnoreLayoutGroups = false;
+ serverPreview.Visible = true;
+ serverPreview.IgnoreLayoutGroups = false;
+ serverListHolder.Recalculate();
+ }
serverInfo.CreatePreviewWindow(serverPreview);
+ btn.Children.ForEach(c => c.SpriteEffects = serverPreview.Visible ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
}
return true;
}
};
- serverList.OnSelected += SelectServer;
+ //server preview panel --------------------------------------------------
- serverPreview = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), serverListHolder.RectTransform, Anchor.Center));
+ serverPreviewToggleButton = new GUIButton(new RectTransform(new Vector2(0.02f, 1.0f), serverListHolder.RectTransform, Anchor.CenterRight) { MinSize = new Point(20, 0) }, style: "UIToggleButton")
+ {
+ Visible = false,
+ OnClicked = (btn, userdata) =>
+ {
+ serverPreview.RectTransform.RelativeSize = new Vector2(0.25f, 1.0f);
+ serverPreview.Visible = !serverPreview.Visible;
+ serverPreview.IgnoreLayoutGroups = !serverPreview.Visible;
+ serverListHolder.Recalculate();
+ btn.Children.ForEach(c => c.SpriteEffects = serverPreview.Visible ? SpriteEffects.None : SpriteEffects.FlipHorizontally);
+ return true;
+ }
+ };
- columnRelativeWidth = new float[] { 0.04f, 0.02f, 0.044f, 0.77f, 0.02f, 0.075f, 0.06f };
+ serverPreview = new GUIFrame(new RectTransform(new Vector2(0.3f, 1.0f), serverListHolder.RectTransform, Anchor.Center), style: null)
+ {
+ Color = new Color(12, 14, 15, 255) * 0.5f,
+ OutlineColor = Color.Black,
+ IgnoreLayoutGroups = true,
+ Visible = false
+ };
- var buttonContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.075f), rightColumn.RectTransform), style: null);
+ // Spacing
+ new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), bottomRow.RectTransform), style: null);
- GUIButton button = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform, Anchor.TopLeft),
+ var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.075f), bottomRow.RectTransform, Anchor.Center), isHorizontal: true)
+ {
+ RelativeSpacing = 0.02f,
+ Stretch = true
+ };
+
+ GUIButton button = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
TextManager.Get("Back"), style: "GUIButtonLarge")
{
OnClicked = GameMain.MainMenuScreen.ReturnToMainMenu
};
- refreshButton = new GUIButton(new RectTransform(new Vector2(buttonContainer.Rect.Height / (float)buttonContainer.Rect.Width, 0.9f), buttonContainer.RectTransform, Anchor.Center),
- "", style: "GUIButtonRefresh") {
-
- ToolTip = TextManager.Get("ServerListRefresh"),
- OnClicked = RefreshServers
+ new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
+ TextManager.Get("ServerListRefresh"), style: "GUIButtonLarge")
+ {
+ OnClicked = (btn, userdata) => { RefreshServers(); return true; }
};
- joinButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform, Anchor.TopRight),
+ /*var directJoinButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
+ TextManager.Get("serverlistdirectjoin"), style: "GUIButtonLarge")
+ {
+ OnClicked = (btn, userdata) => { ShowDirectJoinPrompt(); return true; }
+ };*/
+
+ joinButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.9f), buttonContainer.RectTransform),
TextManager.Get("ServerListJoin"), style: "GUIButtonLarge")
{
- OnClicked = JoinServer,
+ OnClicked = (btn, userdata) =>
+ {
+ if (ipBox.UserData is ServerInfo selectedServer)
+ {
+ JoinServer(selectedServer.IP + ":" + selectedServer.Port, selectedServer.ServerName);
+ }
+ else if (!string.IsNullOrEmpty(ipBox.Text))
+ {
+ JoinServer(ipBox.Text, "");
+ }
+ return true;
+ },
Enabled = false
};
//--------------------------------------------------------
- button.SelectedColor = button.Color;
+ bottomRow.Recalculate();
+ serverListHolder.Recalculate();
+ serverListContainer.Recalculate();
+ labelHolder.RectTransform.MaxSize = new Point(serverList.Content.Rect.Width, int.MaxValue);
+ labelHolder.Recalculate();
+ serverList.Content.RectTransform.SizeChanged += () =>
+ {
+ labelHolder.RectTransform.MaxSize = new Point(serverList.Content.Rect.Width, int.MaxValue);
+ labelHolder.Recalculate();
+ foreach (GUITextBlock labelText in labelTexts)
+ {
+ labelText.Text = ToolBox.LimitString(labelText.ToolTip, labelText.Font, labelText.Rect.Width);
+ }
+ };
+
+ button.SelectedColor = button.Color;
refreshDisableTimer = DateTime.Now;
}
private void OnResolutionChanged()
{
menu.RectTransform.MinSize = new Point(GameMain.GraphicsHeight, 0);
+ labelHolder.RectTransform.MaxSize = new Point(serverList.Content.Rect.Width, int.MaxValue);
+ foreach (GUITextBlock labelText in labelTexts)
+ {
+ labelText.Text = ToolBox.LimitString(labelText.ToolTip, labelText.Font, labelText.Rect.Width);
+ }
}
+ private bool SortList(GUIButton button, object obj)
+ {
+ if (!(obj is string sortBy)) { return false; }
+ SortList(sortBy, toggle: true);
+ return true;
+ }
+
+ private void SortList(string sortBy, bool toggle)
+ {
+ GUIButton button = labelHolder.GetChildByUserData(sortBy) as GUIButton;
+ if (button == null) { return; }
+
+ sortedBy = sortBy;
+
+ var arrowUp = button.GetChildByUserData("arrowup");
+ var arrowDown = button.GetChildByUserData("arrowdown");
+
+ //disable arrow buttons in other labels
+ foreach (var child in button.Parent.Children)
+ {
+ if (child != button)
+ {
+ child.GetChildByUserData("arrowup").Visible = false;
+ child.GetChildByUserData("arrowdown").Visible = false;
+ }
+ }
+
+ bool ascending = arrowUp.Visible;
+ if (toggle)
+ {
+ ascending = !ascending;
+ }
+
+ arrowUp.Visible = ascending;
+ arrowDown.Visible = !ascending;
+ serverList.Content.RectTransform.SortChildren((c1, c2) =>
+ {
+ ServerInfo s1 = c1.GUIComponent.UserData as ServerInfo;
+ ServerInfo s2 = c2.GUIComponent.UserData as ServerInfo;
+
+ switch (sortBy)
+ {
+ case "ServerListCompatible":
+ bool? s1Compatible = NetworkMember.IsCompatible(GameMain.Version.ToString(), s1.GameVersion);
+ if (!s1.ContentPackageHashes.Any()) { s1Compatible = null; }
+ if (s1Compatible.HasValue) { s1Compatible = s1Compatible.Value && s1.ContentPackagesMatch(GameMain.SelectedPackages); };
+
+ bool? s2Compatible = NetworkMember.IsCompatible(GameMain.Version.ToString(), s2.GameVersion);
+ if (!s2.ContentPackageHashes.Any()) { s2Compatible = null; }
+ if (s2Compatible.HasValue) { s2Compatible = s2Compatible.Value && s2.ContentPackagesMatch(GameMain.SelectedPackages); };
+
+ //convert to int to make sorting easier
+ //1 Compatible
+ //0 Unknown
+ //-1 Incompatible
+ int s1CompatibleInt = s1Compatible.HasValue ?
+ (s1Compatible.Value ? 1 : -1) :
+ 0;
+ int s2CompatibleInt = s2Compatible.HasValue ?
+ (s2Compatible.Value ? 1 : -1) :
+ 0;
+ return s2CompatibleInt.CompareTo(s1CompatibleInt) * (ascending ? 1 : -1);
+ case "ServerListHasPassword":
+ if (s1.HasPassword == s2.HasPassword) { return 0; }
+ return (s1.HasPassword ? 1 : -1) * (ascending ? 1 : -1);
+ case "ServerListName":
+ return s1.ServerName.CompareTo(s2.ServerName) * (ascending ? 1 : -1);
+ case "ServerListRoundStarted":
+ if (s1.GameStarted == s2.GameStarted) { return 0; }
+ return (s1.GameStarted ? 1 : -1) * (ascending ? 1 : -1);
+ case "ServerListPlayers":
+ return s2.PlayerCount.CompareTo(s1.PlayerCount) * (ascending ? 1 : -1);
+ case "ServerListPing":
+ return s2.Ping.CompareTo(s1.Ping) * (ascending ? 1 : -1);
+ default:
+ return 0;
+ }
+ });
+ }
+
public override void Select()
{
base.Select();
- RefreshServers(null, null);
+ RefreshServers();
}
private void FilterServers()
@@ -192,9 +470,15 @@ namespace Barotrauma
if (!(child.UserData is ServerInfo)) continue;
ServerInfo serverInfo = (ServerInfo)child.UserData;
+ Version remoteVersion = null;
+ if (!string.IsNullOrEmpty(serverInfo.GameVersion))
+ {
+ Version.TryParse(serverInfo.GameVersion, out remoteVersion);
+ }
+
bool incompatible =
(!serverInfo.ContentPackageHashes.Any() && serverInfo.ContentPackagesMatch(GameMain.Config.SelectedContentPackages)) ||
- (!string.IsNullOrEmpty(serverInfo.GameVersion) && serverInfo.GameVersion != GameMain.Version.ToString());
+ (remoteVersion != null && !NetworkMember.IsCompatible(GameMain.Version, remoteVersion));
child.Visible =
serverInfo.ServerName.ToLowerInvariant().Contains(searchBox.Text.ToLowerInvariant()) &&
@@ -216,59 +500,48 @@ namespace Barotrauma
serverList.UpdateScrollBarSize();
}
- private bool RefreshJoinButtonState(GUIComponent component, object obj)
+ /*private void ShowDirectJoinPrompt()
{
- if (obj == null || waitingForRefresh) { return false; }
+ var msgBox = new GUIMessageBox(TextManager.Get("ServerListDirectJoin"), "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") },
+ relativeSize: new Vector2(0.25f, 0.2f), minSize: new Point(400, 150));
- if (!string.IsNullOrWhiteSpace(clientNameBox.Text) && !string.IsNullOrWhiteSpace(ipBox.Text))
+ var content = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.3f), msgBox.InnerFrame.RectTransform, Anchor.Center) { MinSize = new Point(0, 50) })
{
- joinButton.Enabled = true;
- }
- else
+ IgnoreLayoutGroups = true,
+ Stretch = true,
+ RelativeSpacing = 0.05f
+ };
+
+ new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform), TextManager.Get("ServerIP"));
+ var ipBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform));
+
+ var okButton = msgBox.Buttons[0];
+ okButton.Enabled = false;
+ okButton.OnClicked = (btn, userdata) =>
{
- joinButton.Enabled = false;
- }
+ JoinServer(ipBox.Text, "");
+ msgBox.Close();
+ return true;
+ };
- return true;
- }
+ var cancelButton = msgBox.Buttons[1];
+ cancelButton.OnClicked = msgBox.Close;
- private bool SelectServer(GUIComponent component, object obj)
+ ipBox.OnTextChanged += (textBox, text) =>
+ {
+ okButton.Enabled = !string.IsNullOrEmpty(text);
+ return true;
+ };
+ }*/
+
+ private void RefreshServers()
{
- if (obj == null || waitingForRefresh || (!(obj is ServerInfo))) { return false; }
-
- if (!string.IsNullOrWhiteSpace(clientNameBox.Text))
- {
- joinButton.Enabled = true;
- }
- else
- {
- clientNameBox.Flash();
- joinButton.Enabled = false;
- }
-
- ServerInfo serverInfo;
- try
- {
- serverInfo = (ServerInfo)obj;
- ipBox.UserData = serverInfo;
- ipBox.Text = ToolBox.LimitString(serverInfo.ServerName, ipBox.Font, ipBox.Rect.Width);
- }
- catch (InvalidCastException)
- {
- return false;
- }
-
- return true;
- }
-
- private bool RefreshServers(GUIButton button, object obj)
- {
- if (waitingForRefresh) { return false; }
+ if (waitingForRefresh) { return; }
serverList.ClearChildren();
serverPreview.ClearChildren();
-
- ipBox.Text = null;
joinButton.Enabled = false;
+ ipBox.UserData = null;
+ ipBox.Text = "";
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), serverList.Content.RectTransform),
TextManager.Get("RefreshingServerList"), textAlignment: Alignment.Center)
@@ -277,8 +550,6 @@ namespace Barotrauma
};
CoroutineManager.StartCoroutine(WaitForRefresh());
-
- return true;
}
private IEnumerable