(965c31410a) Unstable v0.10.4.0

This commit is contained in:
Juan Pablo Arce
2020-07-21 08:57:50 -03:00
parent 4f8bd39789
commit 33d3a41104
546 changed files with 45952 additions and 25762 deletions
@@ -35,6 +35,26 @@ namespace Barotrauma
}
private static Dictionary<InvSlotType, Sprite> limbSlotIcons;
public static Dictionary<InvSlotType, Sprite> LimbSlotIcons
{
get
{
if (limbSlotIcons == null)
{
limbSlotIcons = new Dictionary<InvSlotType, Sprite>();
int margin = 2;
limbSlotIcons.Add(InvSlotType.Headset, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(384 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.InnerClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(512 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.Card, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(640 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.Head, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(896 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(634, 0, 128, 128)));
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(762, 0, 128, 128)));
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(256 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
}
return limbSlotIcons;
}
}
public const InvSlotType PersonalSlots = InvSlotType.Card | InvSlotType.Headset | InvSlotType.InnerClothes | InvSlotType.OuterClothes | InvSlotType.Head;
@@ -88,7 +108,7 @@ namespace Barotrauma
indicatorGroup = new GUILayoutGroup(new RectTransform(Point.Zero, hideButton.RectTransform)) { IsHorizontal = false };
indicatorGroup.ChildAnchor = Anchor.TopCenter;
indicatorSpriteSize = GUI.Style.GetComponentStyle("EquipmentIndicatorDivingSuit").Sprites[GUIComponent.ComponentState.None][0].Sprite.size;
indicatorSpriteSize = GUI.Style.GetComponentStyle("EquipmentIndicatorDivingSuit").GetDefaultSprite().size;
indicators[0] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorDivingSuit");
indicators[1] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorID");
@@ -115,20 +135,6 @@ namespace Barotrauma
hidePersonalSlots = false;
if (limbSlotIcons == null)
{
limbSlotIcons = new Dictionary<InvSlotType, Sprite>();
int margin = 2;
limbSlotIcons.Add(InvSlotType.Headset, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(384 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.InnerClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(512 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.Card, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(640 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.Head, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(896 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(634, 0, 128, 128)));
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(762, 0, 128, 128)));
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(256 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
}
SlotPositions = new Vector2[SlotTypes.Length];
CurrentLayout = Layout.Default;
SetSlotPositions(layout);
@@ -522,14 +528,7 @@ namespace Barotrauma
if (hoverOnInventory) { HideTimer = 0.5f; }
if (HideTimer > 0.0f) { HideTimer -= deltaTime; }
for (int i = 0; i < capacity; i++)
{
if (Items[i] != null && Items[i] != draggingItem && Character.Controlled?.Inventory == this &&
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(slots[i].InventoryKeyIndex))
{
QuickUseItem(Items[i], true, false, true);
}
}
UpdateSlotInput();
//force personal slots open if an item is running out of battery/fuel/oxygen/etc
if (hidePersonalSlots)
@@ -685,6 +684,18 @@ namespace Barotrauma
doubleClickedItem = null;
}
public void UpdateSlotInput()
{
for (int i = 0; i < capacity; i++)
{
if (Items[i] != null && Items[i] != draggingItem && Character.Controlled?.Inventory == this &&
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(slots[i].InventoryKeyIndex))
{
QuickUseItem(Items[i], true, false, true);
}
}
}
private void HandleButtonEquipStates(Item item, InventorySlot slot, float deltaTime)
{
slot.EquipButtonState = slot.EquipButtonRect.Contains(PlayerInput.MousePosition) ?
@@ -1084,9 +1095,9 @@ namespace Barotrauma
!Items[i].AllowedSlots.Any(a => a != InvSlotType.Any))
{
//draw limb icons on empty slots
if (limbSlotIcons.ContainsKey(SlotTypes[i]))
if (LimbSlotIcons.ContainsKey(SlotTypes[i]))
{
var icon = limbSlotIcons[SlotTypes[i]];
var icon = LimbSlotIcons[SlotTypes[i]];
icon.Draw(spriteBatch, slots[i].Rect.Center.ToVector2() + slots[i].DrawOffset, GUI.Style.EquipmentSlotIconColor, origin: icon.size / 2, scale: slots[i].Rect.Width / icon.size.X);
}
continue;
@@ -1096,12 +1107,12 @@ namespace Barotrauma
//draw hand icons if the item is equipped in a hand slot
if (IsInLimbSlot(Items[i], InvSlotType.LeftHand))
{
var icon = limbSlotIcons[InvSlotType.LeftHand];
var icon = LimbSlotIcons[InvSlotType.LeftHand];
icon.Draw(spriteBatch, new Vector2(slots[i].Rect.X, slots[i].Rect.Bottom) + slots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.35f, icon.size.Y * 0.75f), scale: slots[i].Rect.Width / icon.size.X * 0.7f);
}
if (IsInLimbSlot(Items[i], InvSlotType.RightHand))
{
var icon = limbSlotIcons[InvSlotType.RightHand];
var icon = LimbSlotIcons[InvSlotType.RightHand];
icon.Draw(spriteBatch, new Vector2(slots[i].Rect.Right, slots[i].Rect.Bottom) + slots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.65f, icon.size.Y * 0.75f), scale: slots[i].Rect.Width / icon.size.X * 0.7f);
}
@@ -48,6 +48,8 @@ namespace Barotrauma.Items.Components
private void UpdateConvexHulls()
{
if (item.Removed) { return; }
doorRect = new Rectangle(
item.Rect.Center.X - (int)(doorSprite.size.X / 2 * item.Scale),
item.Rect.Y - item.Rect.Height / 2 + (int)(doorSprite.size.Y / 2.0f * item.Scale),
@@ -92,8 +94,8 @@ namespace Barotrauma.Items.Components
}
}
}
if (convexHull == null) return;
if (convexHull == null) { return; }
if (rect.Height == 0 || rect.Width == 0)
{
@@ -128,7 +130,7 @@ namespace Barotrauma.Items.Components
if (brokenSprite == null)
{
//broken doors turn black if no broken sprite has been configured
color *= (item.Condition / item.Prefab.Health);
color *= (item.Condition / item.MaxCondition);
color.A = 255;
}
@@ -162,10 +164,10 @@ namespace Barotrauma.Items.Components
color, 0.0f, doorSprite.Origin, item.Scale, SpriteEffects.None, doorSprite.Depth);
}
if (brokenSprite != null && item.Health < item.Prefab.Health)
if (brokenSprite != null && item.Health < item.MaxCondition)
{
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f, 1.0f - item.Health / item.Prefab.Health) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.Prefab.Health : 1.0f;
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f, 1.0f - item.Health / item.MaxCondition) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
spriteBatch.Draw(brokenSprite.Texture, pos,
new Rectangle((int)(brokenSprite.SourceRect.X + brokenSprite.size.X * openState), brokenSprite.SourceRect.Y,
(int)(brokenSprite.size.X * (1.0f - openState)), (int)brokenSprite.size.Y),
@@ -188,10 +190,10 @@ namespace Barotrauma.Items.Components
color, 0.0f, doorSprite.Origin, item.Scale, SpriteEffects.None, doorSprite.Depth);
}
if (brokenSprite != null && item.Health < item.Prefab.Health)
if (brokenSprite != null && item.Health < item.MaxCondition)
{
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - item.Health / item.Prefab.Health, 1.0f) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.Prefab.Health : 1.0f;
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - item.Health / item.MaxCondition, 1.0f) : Vector2.One;
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
spriteBatch.Draw(brokenSprite.Texture, pos,
new Rectangle(brokenSprite.SourceRect.X, (int)(brokenSprite.SourceRect.Y + brokenSprite.size.Y * openState),
(int)brokenSprite.size.X, (int)(brokenSprite.size.Y * (1.0f - openState))),
@@ -114,6 +114,7 @@ namespace Barotrauma.Items.Components
protected override void RemoveComponentSpecific()
{
base.RemoveComponentSpecific();
crosshairSprite?.Remove();
crosshairSprite = null;
crosshairPointerSprite?.Remove();
@@ -186,7 +186,6 @@ namespace Barotrauma.Items.Components
}
}
private bool shouldMuffleLooping;
private float lastMuffleCheckTime;
private ItemSound loopingSound;
@@ -295,8 +294,6 @@ namespace Barotrauma.Items.Components
PlaySound(matchingSounds[index], item.WorldPosition);
}
}
private void PlaySound(ItemSound itemSound, Vector2 position)
{
if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > itemSound.Range * itemSound.Range)
@@ -387,7 +384,6 @@ namespace Barotrauma.Items.Components
return true;
}
public ItemComponent GetLinkUIToComponent()
{
if (string.IsNullOrEmpty(LinkUIToComponent))
@@ -431,13 +427,8 @@ namespace Barotrauma.Items.Components
DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - GUIFrame defined as rect, use RectTransform instead.");
break;
}
Color? color = null;
if (subElement.Attribute("color") != null) color = subElement.GetAttributeColor("color", Color.White);
string style = subElement.Attribute("style") == null ?
null : subElement.GetAttributeString("style", "");
GuiFrame = new GUIFrame(RectTransform.Load(subElement, GUI.Canvas.ItemComponentHolder, Anchor.Center), style, color);
DefaultLayout = GUILayoutSettings.Load(subElement);
GuiFrameSource = subElement;
ReloadGuiFrame();
break;
case "alternativelayout":
AlternativeLayout = GUILayoutSettings.Load(subElement);
@@ -501,6 +492,42 @@ namespace Barotrauma.Items.Components
return true; //element processed
}
private XElement GuiFrameSource;
protected void ReleaseGuiFrame()
{
if (GuiFrame != null)
{
GuiFrame.RectTransform.Parent = null;
}
}
protected void ReloadGuiFrame()
{
if (GuiFrame != null)
{
ReleaseGuiFrame();
}
Color? color = null;
if (GuiFrameSource.Attribute("color") != null)
{
color = GuiFrameSource.GetAttributeColor("color", Color.White);
}
string style = GuiFrameSource.Attribute("style") == null ? null : GuiFrameSource.GetAttributeString("style", "");
GuiFrame = new GUIFrame(RectTransform.Load(GuiFrameSource, GUI.Canvas.ItemComponentHolder, Anchor.Center), style, color);
DefaultLayout = GUILayoutSettings.Load(GuiFrameSource);
if (GuiFrame != null)
{
GuiFrame.RectTransform.ParentChanged += OnGUIParentChanged;
}
GameMain.Instance.ResolutionChanged += OnResolutionChanged;
}
/// <summary>
/// Overload this method and implement. The method is automatically called when the resolution changes.
/// </summary>
protected virtual void CreateGUI() { }
//Starts a coroutine that will read the correct state of the component from the NetBuffer when correctionTimer reaches zero.
protected void StartDelayedCorrection(ServerNetObject type, IReadMessage buffer, float sendingTime, bool waitForMidRoundSync = false)
{
@@ -530,5 +557,29 @@ namespace Barotrauma.Items.Components
yield return CoroutineStatus.Success;
}
/// <summary>
/// Launches when the parent of the GuiFrame is changed.
/// </summary>
protected void OnGUIParentChanged(RectTransform newParent)
{
if (newParent == null)
{
// Make sure to unregister. It doesn't matter if we haven't ever registered to the event.
GameMain.Instance.ResolutionChanged -= OnResolutionChangedPrivate;
}
}
protected virtual void OnResolutionChanged() { }
private void OnResolutionChangedPrivate()
{
if (RecreateGUIOnResolutionChange)
{
ReloadGuiFrame();
CreateGUI();
}
OnResolutionChanged();
}
}
}
@@ -13,8 +13,6 @@ namespace Barotrauma.Items.Components
private GUICustomComponent guiCustomComponent;
private Point prevResolution;
public Sprite InventoryTopSprite
{
get { return inventoryTopSprite; }
@@ -115,16 +113,16 @@ namespace Barotrauma.Items.Components
{
CanBeFocused = false
};
GuiFrame.RectTransform.ParentChanged += OnGUIParentChanged;
}
else
{
//if a GUIFrame has been defined, draw the inventory inside it
CreateGUI();
prevResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
}
}
private void CreateGUI()
protected override void CreateGUI()
{
var content = new GUIFrame(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset },
style: null)
@@ -167,16 +165,6 @@ namespace Barotrauma.Items.Components
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
{
if (hideItems || (item.body != null && !item.body.Enabled)) { return; }
if ((prevResolution.X > 0 && prevResolution.Y > 0) &&
(prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight))
{
GuiFrame.ClearChildren();
CreateGUI();
prevResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
}
DrawContainedItems(spriteBatch, itemDepth);
}
@@ -238,7 +226,7 @@ namespace Barotrauma.Items.Components
if (item.FlippedY) { origin.Y = containedItem.Sprite.SourceRect.Height - origin.Y; }
float containedSpriteDepth = ContainedSpriteDepth < 0.0f ? containedItem.Sprite.Depth : ContainedSpriteDepth;
containedSpriteDepth = itemDepth + (containedSpriteDepth - item.SpriteDepth) / 10000.0f;
containedSpriteDepth = itemDepth + (containedSpriteDepth - (item.Sprite?.Depth ?? item.SpriteDepth)) / 10000.0f;
containedItem.Sprite.Draw(
spriteBatch,
@@ -20,7 +20,7 @@ namespace Barotrauma.Items.Components
private float[] charWidths;
[Serialize("0,0,0,0", true, description: "The amount of padding around the text in pixels (left,top,right,bottom). ")]
[Serialize("0,0,0,0", true, description: "The amount of padding around the text in pixels (left,top,right,bottom).")]
public Vector4 Padding
{
get { return TextBlock.Padding; }
@@ -34,7 +34,7 @@ namespace Barotrauma.Items.Components
get { return text; }
set
{
if (value == text || item.Rect.Width < 5) return;
if (value == text || item.Rect.Width < 5) { return; }
if (TextBlock.Rect.Width != item.Rect.Width || textBlock.Rect.Height != item.Rect.Height)
{
@@ -64,7 +64,7 @@ namespace Barotrauma.Items.Components
get { return textColor; }
set
{
if (textBlock != null) textBlock.TextColor = value;
if (textBlock != null) { textBlock.TextColor = value; }
textColor = value;
}
}
@@ -75,7 +75,7 @@ namespace Barotrauma.Items.Components
get { return textBlock == null ? 1.0f : textBlock.TextScale; }
set
{
if (textBlock != null) textBlock.TextScale = MathHelper.Clamp(value, 0.1f, 10.0f);
if (textBlock != null) { textBlock.TextScale = MathHelper.Clamp(value, 0.1f, 10.0f); }
}
}
@@ -107,7 +107,7 @@ namespace Barotrauma.Items.Components
if (textBlock == null)
{
textBlock = new GUITextBlock(new RectTransform(item.Rect.Size), "",
textColor: textColor, font: GUI.UnscaledSmallFont, textAlignment: Alignment.Center, wrap: true, style: null)
textColor: textColor, font: GUI.UnscaledSmallFont, textAlignment: scrollable ? Alignment.CenterLeft : Alignment.Center, wrap: true, style: null)
{
TextDepth = item.SpriteDepth - 0.00001f,
RoundToNearestPixel = false,
@@ -27,8 +27,9 @@ namespace Barotrauma.Items.Components
if (backgroundSprite == null) { return; }
backgroundSprite.DrawTiled(spriteBatch,
new Vector2(item.DrawPosition.X - item.Rect.Width / 2, -(item.DrawPosition.Y + item.Rect.Height / 2)) - backgroundSprite.Origin,
new Vector2(backgroundSprite.size.X, item.Rect.Height), color: item.Color,
new Vector2(item.DrawPosition.X - item.Rect.Width / 2 * item.Scale, -(item.DrawPosition.Y + item.Rect.Height / 2)) - backgroundSprite.Origin * item.Scale,
new Vector2(backgroundSprite.size.X * item.Scale, item.Rect.Height), color: item.Color,
textureScale: Vector2.One * item.Scale,
depth: BackgroundSpriteDepth);
}
@@ -1,5 +1,6 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework.Graphics;
using System.ComponentModel;
namespace Barotrauma.Items.Components
{
@@ -74,6 +75,21 @@ namespace Barotrauma.Items.Components
}
}
#if DEBUG
public override void CreateEditingHUD(SerializableEntityEditor editor)
{
base.CreateEditingHUD(editor);
foreach (LimbPos limbPos in limbPositions)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(limbPos);
PropertyDescriptor limbPosProperty = properties.Find("Position", false);
editor.CreateVector2Field(limbPos, new SerializableProperty(limbPosProperty), limbPos.Position, limbPos.LimbType.ToString(), "");
}
}
#endif
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
{
State = msg.ReadBoolean();
@@ -23,17 +23,15 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific(XElement element)
{
CreateGUI();
GameMain.Instance.OnResolutionChanged += RecreateGUI;
}
private void RecreateGUI()
protected override void OnResolutionChanged()
{
GuiFrame.ClearChildren();
CreateGUI();
base.OnResolutionChanged();
OnItemLoadedProjSpecific();
}
private void CreateGUI()
protected override void CreateGUI()
{
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.90f, 0.80f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
{
@@ -170,10 +168,5 @@ namespace Barotrauma.Items.Components
SetActive(msg.ReadBoolean());
progressTimer = msg.ReadSingle();
}
protected override void RemoveComponentSpecific()
{
GameMain.Instance.OnResolutionChanged -= RecreateGUI;
}
}
}
@@ -42,17 +42,15 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific()
{
CreateGUI();
GameMain.Instance.OnResolutionChanged += RecreateGUI;
}
private void RecreateGUI()
protected override void OnResolutionChanged()
{
GuiFrame.ClearChildren();
CreateGUI();
base.OnResolutionChanged();
OnItemLoadedProjSpecific();
}
private void CreateGUI()
protected override void CreateGUI()
{
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter);
@@ -242,8 +240,8 @@ namespace Barotrauma.Items.Components
var item1 = c1.GUIComponent.UserData as FabricationRecipe;
var item2 = c2.GUIComponent.UserData as FabricationRecipe;
bool hasSkills1 = DegreeOfSuccess(character, item1.RequiredSkills) >= 0.5f;
bool hasSkills2 = DegreeOfSuccess(character, item2.RequiredSkills) >= 0.5f;
bool hasSkills1 = FabricationDegreeOfSuccess(character, item1.RequiredSkills) >= 0.5f;
bool hasSkills2 = FabricationDegreeOfSuccess(character, item2.RequiredSkills) >= 0.5f;
if (hasSkills1 != hasSkills2)
{
@@ -267,7 +265,7 @@ namespace Barotrauma.Items.Components
AutoScaleHorizontal = true,
CanBeFocused = false
};
var firstinSufficient = itemList.Content.Children.FirstOrDefault(c => c.UserData is FabricationRecipe fabricableItem && DegreeOfSuccess(character, fabricableItem.RequiredSkills) < 0.5f);
var firstinSufficient = itemList.Content.Children.FirstOrDefault(c => c.UserData is FabricationRecipe fabricableItem && FabricationDegreeOfSuccess(character, fabricableItem.RequiredSkills) < 0.5f);
if (firstinSufficient != null)
{
insufficientSkillsText.RectTransform.RepositionChildInHierarchy(itemList.Content.RectTransform.GetChildIndex(firstinSufficient.RectTransform));
@@ -476,7 +474,7 @@ namespace Barotrauma.Items.Components
List<Skill> inadequateSkills = new List<Skill>();
if (user != null)
{
inadequateSkills = selectedItem.RequiredSkills.FindAll(skill => user.GetSkillLevel(skill.Identifier) < skill.Level);
inadequateSkills = selectedItem.RequiredSkills.FindAll(skill => user.GetSkillLevel(skill.Identifier) < Math.Round(skill.Level * SkillRequirementMultiplier));
}
if (selectedItem.RequiredSkills.Any())
@@ -489,13 +487,13 @@ namespace Barotrauma.Items.Components
};
foreach (Skill skill in selectedItem.RequiredSkills)
{
text += TextManager.Get("SkillName." + skill.Identifier) + " " + TextManager.Get("Lvl").ToLower() + " " + skill.Level;
text += TextManager.Get("SkillName." + skill.Identifier) + " " + TextManager.Get("Lvl").ToLower() + " " + Math.Round(skill.Level * SkillRequirementMultiplier);
if (skill != selectedItem.RequiredSkills.Last()) { text += "\n"; }
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), text, font: GUI.SmallFont);
}
float degreeOfSuccess = user == null ? 0.0f : DegreeOfSuccess(user, selectedItem.RequiredSkills);
float degreeOfSuccess = user == null ? 0.0f : FabricationDegreeOfSuccess(user, selectedItem.RequiredSkills);
if (degreeOfSuccess > 0.5f) { degreeOfSuccess = 1.0f; }
float requiredTime = user == null ? selectedItem.RequiredTime : GetRequiredTime(selectedItem, user);
@@ -621,10 +619,5 @@ namespace Barotrauma.Items.Components
StartFabricating(fabricationRecipes[itemIndex], user);
}
}
protected override void RemoveComponentSpecific()
{
GameMain.Instance.OnResolutionChanged -= RecreateGUI;
}
}
}
@@ -24,7 +24,17 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific(XElement element)
{
noPowerTip = TextManager.Get("SteeringNoPowerTip");
CreateGUI();
}
protected override void OnResolutionChanged()
{
base.OnResolutionChanged();
CreateHUD();
}
protected override void CreateGUI()
{
GuiFrame.RectTransform.RelativeOffset = new Vector2(0.05f, 0.0f);
GuiFrame.CanBeFocused = true;
new GUICustomComponent(new RectTransform(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin, GuiFrame.RectTransform, Anchor.Center) { AbsoluteOffset = GUIStyle.ItemFrameOffset },
@@ -53,7 +63,11 @@ namespace Barotrauma.Items.Components
hullAirQualityText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), hullInfoContainer.RectTransform), "") { Wrap = true };
hullWaterText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), hullInfoContainer.RectTransform), "") { Wrap = true };
hullInfoFrame.Children.ForEach(c => { c.CanBeFocused = false; c.Children.ForEach(c2 => c2.CanBeFocused = false); });
hullInfoFrame.Children.ForEach(c =>
{
c.CanBeFocused = false;
c.Children.ForEach(c2 => c2.CanBeFocused = false);
});
}
public override void AddToGUIUpdateList()
@@ -72,7 +86,7 @@ namespace Barotrauma.Items.Components
{
submarineContainer.ClearChildren();
if (item.Submarine == null) return;
if (item.Submarine == null) { return; }
item.Submarine.CreateMiniMap(submarineContainer);
displayedSubs.Clear();
@@ -125,10 +139,8 @@ namespace Barotrauma.Items.Components
GUI.Style.Orange * (float)Math.Abs(Math.Sin(Timing.TotalTime)), Color.Black * 0.8f, font: GUI.SubHeadingFont);
return;
}
if (!submarineContainer.Children.Any()) { return; }
foreach (GUIComponent child in submarineContainer.Children.First().Children)
foreach (GUIComponent child in submarineContainer.Children.FirstOrDefault()?.Children)
{
if (child.UserData is Hull hull)
{
@@ -177,9 +189,19 @@ namespace Barotrauma.Items.Components
HashSet<Submarine> subs = new HashSet<Submarine>();
foreach (Hull hull in Hull.hullList)
{
if (hull.Submarine == null) continue;
if (hull.Submarine == null) { continue; }
var hullFrame = submarineContainer.Children.FirstOrDefault()?.FindChild(hull);
if (hullFrame == null) continue;
if (hullFrame == null) { continue; }
hullFrame.Visible = true;
if (!submarineContainer.Rect.Contains(hullFrame.Rect))
{
if (hull.Submarine.Info.Type != SubmarineType.Player)
{
hullFrame.Visible = false;
continue;
}
}
hullDatas.TryGetValue(hull, out HullData hullData);
if (hullData == null)
@@ -294,7 +316,7 @@ namespace Barotrauma.Items.Components
foreach (Submarine sub in subs)
{
if (sub.HullVertices == null) { continue; }
if (sub.HullVertices == null || sub.Info.IsOutpost) { continue; }
Rectangle worldBorders = sub.GetDockedBorders();
worldBorders.Location += sub.WorldPosition.ToPoint();
@@ -0,0 +1,42 @@
namespace Barotrauma.Items.Components
{
partial class OutpostTerminal : ItemComponent
{
private SubmarineSelection selectionUI;
public override bool Select(Character character)
{
if (GameMain.GameSession?.Campaign == null)
{
return false;
}
if (selectionUI == null)
{
selectionUI = new SubmarineSelection(true, null, GUICanvas.Instance.ItemComponentHolder);
}
GuiFrame = selectionUI.GuiFrame;
selectionUI.RefreshSubmarineDisplay(true);
IsActive = true;
return base.Select(character);
}
public override void Update(float deltaTime, Camera cam)
{
if (Character.Controlled?.SelectedConstruction != item)
{
IsActive = false;
return;
}
base.Update(deltaTime, cam);
if (selectionUI != null)
{
selectionUI.Update();
}
}
}
}
@@ -157,16 +157,15 @@ namespace Barotrauma.Items.Components
}
}
CreateGUI();
GameMain.Instance.OnResolutionChanged += RecreateGUI;
}
private void RecreateGUI()
protected override void OnResolutionChanged()
{
GuiFrame.ClearChildren();
CreateGUI();
base.OnResolutionChanged();
UpdateGUIElements();
}
private void CreateGUI()
protected override void CreateGUI()
{
bool isConnectedToSteering = item.GetComponent<Steering>() != null;
Vector2 size = isConnectedToSteering ? controlBoxSize : new Vector2(controlBoxSize.X * 2.0f, controlBoxSize.Y);
@@ -667,23 +666,27 @@ namespace Barotrauma.Items.Components
signalWarningText.Visible = false;
}
if (GameMain.GameSession == null) { return; }
if (GameMain.GameSession == null || Level.Loaded == null) { return; }
if (Level.Loaded == null) { return; }
if (Level.Loaded.StartLocation != null)
{
DrawMarker(spriteBatch,
Level.Loaded.StartLocation.Name,
"outpost",
Level.Loaded.StartLocation.Name,
Level.Loaded.StartPosition, transducerCenter,
displayScale, center, DisplayRadius);
}
DrawMarker(spriteBatch,
GameMain.GameSession.StartLocation.Name,
"outpost",
GameMain.GameSession.StartLocation.Name,
Level.Loaded.StartPosition, transducerCenter,
displayScale, center, DisplayRadius);
DrawMarker(spriteBatch,
GameMain.GameSession.EndLocation.Name,
"outpost",
GameMain.GameSession.EndLocation.Name,
Level.Loaded.EndPosition, transducerCenter,
displayScale, center, DisplayRadius);
if (Level.Loaded.EndLocation != null && Level.Loaded.Type == LevelData.LevelType.LocationConnection)
{
DrawMarker(spriteBatch,
Level.Loaded.EndLocation.Name,
"outpost",
Level.Loaded.EndLocation.Name,
Level.Loaded.EndPosition, transducerCenter,
displayScale, center, DisplayRadius);
}
foreach (AITarget aiTarget in AITarget.List)
{
@@ -1444,8 +1447,6 @@ namespace Barotrauma.Items.Components
sprite.Remove();
}
targetIcons.Clear();
GameMain.Instance.OnResolutionChanged -= RecreateGUI;
}
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
@@ -53,6 +53,8 @@ namespace Barotrauma.Items.Components
private bool? swapDestinationOrder;
private GUIMessageBox enterOutpostPrompt;
private bool levelStartSelected;
public bool LevelStartSelected
{
@@ -105,10 +107,9 @@ namespace Barotrauma.Items.Components
}
}
CreateGUI();
GameMain.Instance.OnResolutionChanged += RecreateGUI;
}
private void CreateGUI()
protected override void CreateGUI()
{
controlContainer = new GUIFrame(new RectTransform(new Vector2(Sonar.controlBoxSize.X, 1 - Sonar.controlBoxSize.Y * 2), GuiFrame.RectTransform, Anchor.CenterLeft), "ItemUI");
var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center)
@@ -220,11 +221,12 @@ namespace Barotrauma.Items.Components
};
levelEndTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.333f), paddedAutoPilotControls.RectTransform, Anchor.BottomCenter),
GameMain.GameSession?.EndLocation == null ? "" : ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, textLimit),
(GameMain.GameSession?.EndLocation == null || Level.IsLoadedOutpost) ? "" : ToolBox.LimitString(GameMain.GameSession.EndLocation.Name, textLimit),
font: GUI.SmallFont, style: "GUIRadioButton")
{
Enabled = autoPilot,
Selected = levelEndSelected,
Visible = GameMain.GameSession?.EndLocation != null,
OnSelected = tickBox =>
{
if (levelEndSelected != tickBox.Selected)
@@ -321,7 +323,7 @@ namespace Barotrauma.Items.Components
};
break;
}
new GUITextBlock(new RectTransform(Vector2.One, left.RectTransform), leftText, font: GUI.SubHeadingFont, wrap: true, textAlignment: Alignment.CenterRight);
new GUITextBlock(new RectTransform(Vector2.One, left.RectTransform), leftText, font: GUI.SubHeadingFont, wrap: leftText.Contains(' '), textAlignment: Alignment.CenterRight);
new GUITextBlock(new RectTransform(Vector2.One, center.RectTransform), centerText, font: GUI.Font, textAlignment: Alignment.Center) { Padding = Vector4.Zero };
var digitalFrame = new GUIFrame(new RectTransform(Vector2.One, right.RectTransform), style: "DigitalFrameDark");
new GUITextBlock(new RectTransform(Vector2.One * 0.85f, digitalFrame.RectTransform, Anchor.Center), "12345", GUI.Style.TextColorDark, GUI.DigitalFont, Alignment.CenterRight)
@@ -347,18 +349,47 @@ namespace Barotrauma.Items.Components
{
OnClicked = (btn, userdata) =>
{
if (GameMain.Client == null)
if (GameMain.GameSession?.Campaign != null)
{
item.SendSignal(0, "1", "toggle_docking", sender: null);
}
else
{
dockingNetworkMessagePending = true;
item.CreateClientEvent(this);
if (Level.IsLoadedOutpost &&
DockingSources.Any(d => d.Docked && (d.DockingTarget?.Item.Submarine?.Info?.IsOutpost ?? false)))
{
GameMain.GameSession.Campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
GameMain.GameSession.Campaign.ShowCampaignUI = true;
return false;
}
else if (!Level.IsLoadedOutpost && DockingModeEnabled && ActiveDockingSource != null &&
!ActiveDockingSource.Docked && (DockingTarget?.Item?.Submarine?.Info.IsOutpost ?? false))
{
enterOutpostPrompt = new GUIMessageBox("", TextManager.GetWithVariable("campaignenteroutpostprompt", "[locationname]", DockingTarget.Item.Submarine.Info.Name), new string[] { TextManager.Get("yes"), TextManager.Get("no") });
enterOutpostPrompt.Buttons[0].OnClicked += (btn, userdata) =>
{
SendDockingSignal();
enterOutpostPrompt.Close();
return true;
};
enterOutpostPrompt.Buttons[1].OnClicked += enterOutpostPrompt.Close;
return false;
}
}
SendDockingSignal();
return true;
}
};
void SendDockingSignal()
{
if (GameMain.Client == null)
{
item.SendSignal(0, "1", "toggle_docking", sender: null);
}
else
{
dockingNetworkMessagePending = true;
item.CreateClientEvent(this);
}
}
dockingButton.Font = GUI.SubHeadingFont;
dockingButton.TextBlock.RectTransform.MaxSize = new Point((int)(dockingButton.Rect.Width * 0.7f), int.MaxValue);
dockingButton.TextBlock.AutoScaleHorizontal = true;
@@ -413,10 +444,9 @@ namespace Barotrauma.Items.Components
GameMain.GameSession?.EndLocation == null ? "End" : GameMain.GameSession.EndLocation.Name);
}
private void RecreateGUI()
protected override void OnResolutionChanged()
{
GuiFrame.ClearChildren();
CreateGUI();
base.OnResolutionChanged();
UpdateGUIElements();
}
@@ -600,6 +630,10 @@ namespace Barotrauma.Items.Components
dockingContainer.Visible = DockingModeEnabled;
statusContainer.Visible = !DockingModeEnabled;
if (!DockingModeEnabled)
{
enterOutpostPrompt?.Close();
}
if (DockingModeEnabled && ActiveDockingSource != null)
{
@@ -613,6 +647,10 @@ namespace Barotrauma.Items.Components
dockingButton.Pulsate(Vector2.One, Vector2.One * 1.2f, dockingButton.FlashTimer);
}
}
else
{
enterOutpostPrompt?.Close();
}
}
else if (DockingSources.Any(d => d.Docked))
{
@@ -663,7 +701,8 @@ namespace Barotrauma.Items.Components
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
{
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen)
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen &&
(!GameMain.GameSession?.Campaign?.ShowCampaignUI ?? true) && !GUIMessageBox.MessageBoxes.Any())
{
Vector2 inputPos = PlayerInput.MousePosition - steerArea.Rect.Center.ToVector2();
inputPos.Y = -inputPos.Y;
@@ -800,8 +839,7 @@ namespace Barotrauma.Items.Components
maintainPosIndicator?.Remove();
maintainPosOriginIndicator?.Remove();
steeringIndicator?.Remove();
GameMain.Instance.OnResolutionChanged -= RecreateGUI;
enterOutpostPrompt?.Close();
}
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
@@ -111,27 +111,28 @@ namespace Barotrauma.Items.Components
if (item.FlippedX && item.Prefab.CanSpriteFlipX) { indicatorPos.X = -indicatorPos.X - indicatorSize.X * item.Scale; }
if (item.FlippedY && item.Prefab.CanSpriteFlipY) { indicatorPos.Y = -indicatorPos.Y - indicatorSize.Y * item.Scale; }
if (charge > 0)
if (charge > 0 && capacity > 0)
{
Color indicatorColor = ToolBox.GradientLerp(charge / capacity, Color.Red, Color.Orange, Color.Green);
float chargeRatio = MathHelper.Clamp(charge / capacity, 0.0f, 1.0f);
Color indicatorColor = ToolBox.GradientLerp(chargeRatio, Color.Red, Color.Orange, Color.Green);
if (!isHorizontal)
{
GUI.DrawRectangle(spriteBatch,
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + ((indicatorSize.Y * item.Scale) * (1.0f - charge / capacity))) + indicatorPos,
new Vector2(indicatorSize.X * item.Scale, (indicatorSize.Y * item.Scale) * (charge / capacity)), indicatorColor, true,
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y + ((indicatorSize.Y * item.Scale) * (1.0f - chargeRatio))) + indicatorPos,
new Vector2(indicatorSize.X * item.Scale, (indicatorSize.Y * item.Scale) * chargeRatio), indicatorColor, true,
depth: item.SpriteDepth - 0.00001f);
}
else
{
GUI.DrawRectangle(spriteBatch,
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y) + indicatorPos,
new Vector2((indicatorSize.X * item.Scale) * (charge / capacity), indicatorSize.Y * item.Scale), indicatorColor, true,
new Vector2((indicatorSize.X * item.Scale) * chargeRatio, indicatorSize.Y * item.Scale), indicatorColor, true,
depth: item.SpriteDepth - 0.00001f);
}
}
GUI.DrawRectangle(spriteBatch,
new Vector2(item.DrawPosition.X, -item.DrawPosition.Y) + indicatorPos,
indicatorSize * item.Scale, Color.Black, depth: item.SpriteDepth - 0.00001f);
indicatorSize * item.Scale, Color.Black, depth: item.SpriteDepth - 0.000015f);
}
public void ClientWrite(IWriteMessage msg, object[] extraData)
@@ -83,7 +83,7 @@ namespace Barotrauma.Items.Components
var progressBar = user.UpdateHUDProgressBar(
targetStructure.ID * 1000 + sectionIndex, //unique "identifier" for each wall section
progressBarPos,
1.0f - targetStructure.SectionDamage(sectionIndex) / targetStructure.Health,
MathUtils.InverseLerp(targetStructure.Prefab.MinHealth, targetStructure.Health, targetStructure.Health - targetStructure.SectionDamage(sectionIndex)),
GUI.Style.Red, GUI.Style.Green);
if (progressBar != null) progressBar.Size = new Vector2(60.0f, 20.0f);
@@ -1,4 +1,5 @@
using Barotrauma.Networking;
using System;
using Barotrauma.Networking;
using Barotrauma.Particles;
using Barotrauma.Sounds;
using Microsoft.Xna.Framework;
@@ -49,6 +50,42 @@ namespace Barotrauma.Items.Components
}
partial void InitProjSpecific(XElement element)
{
CreateGUI();
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "emitter":
case "particleemitter":
particleEmitters.Add(new ParticleEmitter(subElement));
float minCondition = subElement.GetAttributeFloat("mincondition", 0.0f);
float maxCondition = subElement.GetAttributeFloat("maxcondition", 100.0f);
if (maxCondition < minCondition)
{
DebugConsole.ThrowError("Invalid damage particle configuration in the Repairable component of " + item.Name + ". MaxCondition needs to be larger than MinCondition.");
float temp = maxCondition;
maxCondition = minCondition;
minCondition = temp;
}
particleEmitterConditionRanges.Add(new Vector2(minCondition, maxCondition));
break;
}
}
}
private void RecreateGUI()
{
if (GuiFrame != null)
{
GuiFrame.ClearChildren();
CreateGUI();
}
}
private void CreateGUI()
{
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.75f), GuiFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
{
@@ -56,7 +93,7 @@ namespace Barotrauma.Items.Components
RelativeSpacing = 0.05f,
CanBeFocused = true
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), paddedFrame.RectTransform),
header, textAlignment: Alignment.TopCenter, font: GUI.LargeFont);
@@ -68,7 +105,7 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < requiredSkills.Count; i++)
{
var skillText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform),
" - " + TextManager.AddPunctuation(':', TextManager.Get("SkillName." + requiredSkills[i].Identifier), ((int) requiredSkills[i].Level).ToString()),
" - " + TextManager.AddPunctuation(':', TextManager.Get("SkillName." + requiredSkills[i].Identifier), ((int) Math.Round(requiredSkills[i].Level * SkillRequirementMultiplier)).ToString()),
font: GUI.SmallFont)
{
UserData = requiredSkills[i]
@@ -111,43 +148,27 @@ namespace Barotrauma.Items.Components
return true;
}
};
foreach (XElement subElement in element.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "emitter":
case "particleemitter":
particleEmitters.Add(new ParticleEmitter(subElement));
float minCondition = subElement.GetAttributeFloat("mincondition", 0.0f);
float maxCondition = subElement.GetAttributeFloat("maxcondition", 100.0f);
if (maxCondition < minCondition)
{
DebugConsole.ThrowError("Invalid damage particle configuration in the Repairable component of " + item.Name + ". MaxCondition needs to be larger than MinCondition.");
float temp = maxCondition;
maxCondition = minCondition;
minCondition = temp;
}
particleEmitterConditionRanges.Add(new Vector2(minCondition, maxCondition));
break;
}
}
}
partial void UpdateProjSpecific(float deltaTime)
{
if (Character.Controlled == null || (Character.Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
if (FakeBrokenTimer > 0.0f)
{
FakeBrokenTimer = 0.0f;
item.FakeBroken = true;
if (Character.Controlled == null || (Character.Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
{
FakeBrokenTimer = 0.0f;
}
else
{
FakeBrokenTimer -= deltaTime;
}
}
else
{
FakeBrokenTimer -= deltaTime;
item.FakeBroken = false;
}
item.FakeBroken = FakeBrokenTimer > 0.0f;
if (!GameMain.IsMultiplayer)
{
@@ -211,7 +232,7 @@ namespace Barotrauma.Items.Components
if (!(c.UserData is Skill skill)) continue;
GUITextBlock textBlock = (GUITextBlock)c;
if (character.GetSkillLevel(skill.Identifier) < skill.Level)
if (character.GetSkillLevel(skill.Identifier) < (skill.Level * SkillRequirementMultiplier))
{
textBlock.TextColor = GUI.Style.Red;
}
@@ -247,6 +268,7 @@ namespace Barotrauma.Items.Components
protected override void RemoveComponentSpecific()
{
base.RemoveComponentSpecific();
repairSoundChannel?.FadeOutAndDispose();
repairSoundChannel = null;
}
@@ -289,7 +289,7 @@ namespace Barotrauma.Items.Components
flashColor * (float)Math.Sin(FlashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f), scale: connectorSpriteScale);
}
if (Wires.Any(w => w != null && w != DraggingConnected))
if (Wires.Any(w => w != null && w != DraggingConnected && !w.Hidden))
{
int screwIndex = (int)Math.Floor(position.Y / 30.0f) % screwSprites.Count;
screwSprites[screwIndex].Draw(spriteBatch, position, scale: connectorSpriteScale);
@@ -18,17 +18,9 @@ namespace Barotrauma.Items.Components
partial void InitProjSpecific(XElement element)
{
CreateGUI();
GameMain.Instance.OnResolutionChanged += RecreateGUI;
}
private void RecreateGUI()
{
GuiFrame.ClearChildren();
CreateGUI();
UpdateLabelsProjSpecific();
}
private void CreateGUI()
protected override void CreateGUI()
{
uiElements.Clear();
var visibleElements = customInterfaceElementList.Where(ciElement => !string.IsNullOrEmpty(ciElement.Label));
@@ -309,10 +301,5 @@ namespace Barotrauma.Items.Components
}
}
}
protected override void RemoveComponentSpecific()
{
GameMain.Instance.OnResolutionChanged -= RecreateGUI;
}
}
}
@@ -187,7 +187,7 @@ namespace Barotrauma.Items.Components
}
if (IsActive && item.ParentInventory?.Owner is Character user && user == Character.Controlled)// && Vector2.Distance(newNodePos, nodes[nodes.Count - 1]) > nodeDistance)
{
if (user.CanInteract)
if (user.CanInteract && currLength < MaxLength)
{
Vector2 gridPos = Character.Controlled.Position;
Vector2 roundedGridPos = new Vector2(
@@ -135,7 +135,7 @@ namespace Barotrauma.Items.Components
Entity targetEntity = Entity.FindEntityByID(dockingTargetID);
if (targetEntity == null || !(targetEntity is Item))
{
DebugConsole.ThrowError("Invalid docking port network event (can't dock to " + targetEntity?.ToString() ?? "null" + ")");
DebugConsole.ThrowError("Invalid docking port network event (can't dock to " + (targetEntity?.ToString() ?? "null") + ")");
return;
}
@@ -260,7 +260,11 @@ namespace Barotrauma
item.Name :
item.Name + '\n' + description;
}
if (item.SpawnedInOutpost)
{
string colorStr = XMLExtensions.ColorToString(GUI.Style.Red);
toolTip = $"‖color:{colorStr}‖{toolTip}‖color:end‖";
}
return toolTip;
}
}
@@ -1127,6 +1131,8 @@ namespace Barotrauma
public static void DrawFront(SpriteBatch spriteBatch)
{
if (GUI.PauseMenuOpen || GUI.SettingsMenuOpen) { return; }
if (GameMain.GameSession?.Campaign != null &&
(GameMain.GameSession.Campaign.ShowCampaignUI || GameMain.GameSession.Campaign.ForceMapUI)) { return; }
subInventorySlotsToDraw.Clear();
subInventorySlotsToDraw.AddRange(highlightedSubInventorySlots);
@@ -1377,6 +1383,17 @@ namespace Barotrauma
sprite.Draw(spriteBatch, itemPos + Vector2.One * 2, Color.Black * 0.6f, rotate: rotation, scale: scale);
}
sprite.Draw(spriteBatch, itemPos, spriteColor, rotation, scale);
if (item.SpawnedInOutpost && CharacterInventory.LimbSlotIcons.ContainsKey(InvSlotType.LeftHand))
{
var stealIcon = CharacterInventory.LimbSlotIcons[InvSlotType.LeftHand];
Vector2 iconSize = new Vector2(25 * GUI.Scale);
stealIcon.Draw(
spriteBatch,
new Vector2(rect.X + iconSize.X * 0.2f, rect.Bottom - iconSize.Y * 1.2f),
color: GUI.Style.Red,
scale: iconSize.X / stealIcon.size.X);
}
}
if (inventory != null &&
@@ -246,7 +246,7 @@ namespace Barotrauma
float fadeInBrokenSpriteAlpha = 0.0f;
float displayCondition = FakeBroken ? 0.0f : condition;
Vector2 drawOffset = Vector2.Zero;
if (displayCondition < Prefab.Health)
if (displayCondition < MaxCondition)
{
for (int i = 0; i < Prefab.BrokenSprites.Count; i++)
{
@@ -299,22 +299,23 @@ namespace Barotrauma
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
decorativeSprite.Sprite.DrawTiled(spriteBatch,
new Vector2(DrawPosition.X + offset.X - rect.Width / 2, -(DrawPosition.Y + offset.Y + rect.Height / 2)),
new Vector2(rect.Width, rect.Height), color: color,
new Vector2(DrawPosition.X + offset.X - rect.Width / 2, -(DrawPosition.Y + offset.Y + rect.Height / 2)),
size, color: color,
textureScale: Vector2.One * Scale,
depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth), 0.999f));
}
}
else
{
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, SpriteRotation, Scale, activeSprite.effects, depth);
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, SpriteRotation, Scale, activeSprite.effects, depth - 0.000001f);
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, SpriteRotation + rotation, Scale, activeSprite.effects, depth);
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, SpriteRotation + rotation, Scale, activeSprite.effects, depth - 0.000001f);
foreach (var decorativeSprite in Prefab.DecorativeSprites)
{
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
float rot = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + offset.X, -(DrawPosition.Y + offset.Y)), color,
SpriteRotation + rotation, decorativeSprite.Scale * Scale, activeSprite.effects,
SpriteRotation + rotation + rot, decorativeSprite.Scale * Scale, activeSprite.effects,
depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth), 0.999f));
}
}
@@ -328,7 +329,7 @@ namespace Barotrauma
if (holdable.Picker.SelectedItems[0] == this)
{
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.RightHand);
if (holdLimb != null)
if (holdLimb?.ActiveSprite != null)
{
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() + depthStep * 2;
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
@@ -340,7 +341,7 @@ namespace Barotrauma
else if (holdable.Picker.SelectedItems[1] == this)
{
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.LeftHand);
if (holdLimb != null)
if (holdLimb?.ActiveSprite != null)
{
depth = holdLimb.ActiveSprite.Depth + holdable.Picker.AnimController.GetDepthOffset() - depthStep * 2;
foreach (WearableSprite wearableSprite in holdLimb.WearingItems)
@@ -368,6 +369,23 @@ namespace Barotrauma
depth: depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth));
}
}
foreach (var upgrade in Upgrades)
{
var upgradeSprites = GetUpgradeSprites(upgrade);
foreach (var decorativeSprite in upgradeSprites)
{
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
var (xOff, yOff) = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + xOff, -(DrawPosition.Y + yOff)), color,
rotation, decorativeSprite.Scale * Scale, activeSprite.effects,
depth: depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth));
}
}
activeSprite.effects = oldEffects;
if (fadeInBrokenSprite != null && fadeInBrokenSprite.Sprite != activeSprite)
@@ -437,6 +455,21 @@ namespace Barotrauma
}
}
private void DrawDecorativeSprite(SpriteBatch spriteBatch, DecorativeSprite decorativeSprite, Color color, float depth)
{
if (!spriteAnimState[decorativeSprite].IsActive) { return; }
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
var ca = (float)Math.Cos(-body.Rotation);
var sa = (float)Math.Sin(-body.Rotation);
Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y);
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + transformedOffset.X, -(DrawPosition.Y + transformedOffset.Y)), color,
-body.Rotation + rotation, decorativeSprite.Scale * Scale, activeSprite.effects,
depth: depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth));
}
partial void OnCollisionProjSpecific(float impact)
{
if (impact > 1.0f &&
@@ -451,6 +484,22 @@ namespace Barotrauma
public void UpdateSpriteStates(float deltaTime)
{
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
foreach (var upgrade in Upgrades)
{
var upgradeSprites = GetUpgradeSprites(upgrade);
foreach (var decorativeSprite in upgradeSprites)
{
var spriteState = spriteAnimState[decorativeSprite];
spriteState.IsActive = true;
foreach (var _ in decorativeSprite.IsActiveConditionals.Where(conditional => !ConditionalMatches(conditional)))
{
spriteState.IsActive = false;
break;
}
}
}
}
public override void UpdateEditing(Camera cam)
@@ -541,12 +590,14 @@ namespace Barotrauma
linkText.TextColor = GUI.Style.Orange;
itemsText.TextColor = GUI.Style.Orange;
}
var buttonContainer = new GUILayoutGroup(new RectTransform(new Point(listBox.Content.Rect.Width, heightScaled)), isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.02f,
CanBeFocused = true
};
new GUIButton(new RectTransform(new Vector2(0.23f, 1.0f), buttonContainer.RectTransform), TextManager.Get("MirrorEntityX"), style: "GUIButtonSmall")
{
ToolTip = TextManager.Get("MirrorEntityXToolTip"),
@@ -588,6 +639,22 @@ namespace Barotrauma
buttonContainer.RectTransform.IsFixedSize = true;
itemEditor.AddCustomContent(buttonContainer, itemEditor.ContentCount);
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Select(b => ((GUIButton)b).TextBlock));
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
{
GUITickBox tickBox = new GUITickBox(new RectTransform(new Point(listBox.Content.Rect.Width, 10)), TextManager.Get("sp.structure.removeiflinkedoutpostdoorinuse.name"))
{
Font = GUI.SmallFont,
Selected = RemoveIfLinkedOutpostDoorInUse,
ToolTip = TextManager.Get("sp.structure.removeiflinkedoutpostdoorinuse.description"),
OnSelected = (tickBox) =>
{
RemoveIfLinkedOutpostDoorInUse = tickBox.Selected;
return true;
}
};
itemEditor.AddCustomContent(tickBox, 1);
}
}
foreach (ItemComponent ic in components)
@@ -667,6 +734,39 @@ namespace Barotrauma
return editingHUD;
}
private List<DecorativeSprite> GetUpgradeSprites(Upgrade upgrade)
{
var upgradeSprites = upgrade.Prefab.DecorativeSprites;
if (Prefab.UpgradeOverrideSprites.ContainsKey(upgrade.Prefab.Identifier))
{
upgradeSprites = Prefab.UpgradeOverrideSprites[upgrade.Prefab.Identifier];
}
return upgradeSprites;
}
public override bool AddUpgrade(Upgrade upgrade, bool createNetworkEvent = false)
{
if (upgrade.Prefab.IsWallUpgrade) { return false; }
bool result = base.AddUpgrade(upgrade, createNetworkEvent);
if (result && !upgrade.Disposed)
{
List<DecorativeSprite> upgradeSprites = GetUpgradeSprites(upgrade);
if (upgradeSprites.Any())
{
foreach (DecorativeSprite decorativeSprite in upgradeSprites)
{
decorativeSprite.Sprite.EnsureLazyLoaded();
spriteAnimState.Add(decorativeSprite, new DecorativeSprite.State());
}
UpdateSpriteStates(0.0f);
}
}
return result;
}
private void CreateTagPicker(GUITextBox textBox, IEnumerable<string> availableTags)
{
var msgBox = new GUIMessageBox("", "", new string[] { TextManager.Get("Cancel") }, new Vector2(0.2f, 0.5f), new Point(300, 400));
@@ -756,6 +856,10 @@ namespace Barotrauma
private readonly List<Rectangle> debugInitialHudPositions = new List<Rectangle>();
private readonly List<ItemComponent> prevActiveHUDs = new List<ItemComponent>();
private readonly List<ItemComponent> activeComponents = new List<ItemComponent>();
private readonly List<ItemComponent> maxPriorityHUDs = new List<ItemComponent>();
public void UpdateHUD(Camera cam, Character character, float deltaTime)
{
bool editingHUDCreated = false;
@@ -774,8 +878,11 @@ namespace Barotrauma
editingHUDRefreshTimer -= deltaTime;
}
List<ItemComponent> prevActiveHUDs = new List<ItemComponent>(activeHUDs);
List<ItemComponent> activeComponents = new List<ItemComponent>(components);
prevActiveHUDs.Clear();
prevActiveHUDs.AddRange(activeHUDs);
activeComponents.Clear();
activeComponents.AddRange(components);
foreach (MapEntity entity in linkedTo)
{
if (prefab.IsLinkAllowed(entity.prefab) && entity is Item i)
@@ -788,12 +895,11 @@ namespace Barotrauma
activeHUDs.Clear();
//the HUD of the component with the highest priority will be drawn
//if all components have a priority of 0, all of them are drawn
List<ItemComponent> maxPriorityHUDs = new List<ItemComponent>();
maxPriorityHUDs.Clear();
bool DrawHud(ItemComponent ic) => ic.ShouldDrawHUD(character) && (ic.CanBeSelected && ic.HasRequiredItems(character, addMessage: false) || (character.HasEquippedItem(this) && ic.DrawHudWhenEquipped));
foreach (ItemComponent ic in activeComponents)
{
if (ic.HudPriority > 0 && ic.ShouldDrawHUD(character) &&
(ic.CanBeSelected || (character.HasEquippedItem(this) && ic.DrawHudWhenEquipped)) &&
(maxPriorityHUDs.Count == 0 || ic.HudPriority >= maxPriorityHUDs[0].HudPriority))
if (ic.HudPriority > 0 && DrawHud(ic) && (maxPriorityHUDs.Count == 0 || ic.HudPriority >= maxPriorityHUDs[0].HudPriority))
{
if (maxPriorityHUDs.Count > 0 && ic.HudPriority > maxPriorityHUDs[0].HudPriority) { maxPriorityHUDs.Clear(); }
maxPriorityHUDs.Add(ic);
@@ -808,8 +914,7 @@ namespace Barotrauma
{
foreach (ItemComponent ic in activeComponents)
{
if (ic.ShouldDrawHUD(character) &&
(ic.CanBeSelected || (character.HasEquippedItem(this) && ic.DrawHudWhenEquipped)))
if (DrawHud(ic))
{
activeHUDs.Add(ic);
}
@@ -914,11 +1019,11 @@ namespace Barotrauma
color = Color.Cyan;
}
}
texts.Add(new ColoredText(ic.DisplayMsg, color, false));
texts.Add(new ColoredText(ic.DisplayMsg, color, false, false));
}
if ((PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift)) && CrewManager.DoesItemHaveContextualOrders(this))
{
texts.Add(new ColoredText(TextManager.ParseInputTypes(TextManager.Get("itemmsgcontextualorders")), Color.Cyan, false));
texts.Add(new ColoredText(TextManager.ParseInputTypes(TextManager.Get("itemmsgcontextualorders")), Color.Cyan, false, false));
}
return texts;
}
@@ -1048,6 +1153,29 @@ namespace Barotrauma
ReadPropertyChange(msg, false);
editingHUDRefreshPending = true;
break;
case NetEntityEvent.Type.Upgrade:
{
string identifier = msg.ReadString();
byte level = msg.ReadByte();
if (UpgradePrefab.Find(identifier) is { } upgradePrefab)
{
Upgrade upgrade = new Upgrade(this, upgradePrefab, level);
byte targetCount = msg.ReadByte();
for (int i = 0; i < targetCount; i++)
{
byte propertyCount = msg.ReadByte();
for (int j = 0; j < propertyCount; j++)
{
float value = msg.ReadSingle();
upgrade.TargetComponents.ElementAt(i).Value[j].SetOriginalValue(value);
}
}
AddUpgrade(upgrade, false);
}
break;
}
case NetEntityEvent.Type.Invalid:
break;
}
@@ -1220,7 +1348,7 @@ namespace Barotrauma
ushort itemId = msg.ReadUInt16();
ushort inventoryId = msg.ReadUInt16();
DebugConsole.Log("Received entity spawn message for item " + itemName + ".");
DebugConsole.Log($"Received entity spawn message for item \"{itemName}\" (identifier: {itemIdentifier}, id: {itemId})");
Vector2 pos = Vector2.Zero;
Submarine sub = null;
@@ -1243,10 +1371,10 @@ namespace Barotrauma
}
}
byte bodyType = msg.ReadByte();
byte teamID = msg.ReadByte();
bool tagsChanged = msg.ReadBoolean();
byte bodyType = msg.ReadByte();
bool spawnedInOutpost = msg.ReadBoolean();
byte teamID = msg.ReadByte();
bool tagsChanged = msg.ReadBoolean();
string tags = "";
if (tagsChanged)
{
@@ -1289,6 +1417,7 @@ namespace Barotrauma
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
errorMsg);
DebugConsole.ThrowError(errorMsg);
inventory = parentItem.GetComponent<ItemContainer>()?.Inventory;
}
else if (parentItem.components[itemContainerIndex] is ItemContainer container)
{
@@ -1307,7 +1436,8 @@ namespace Barotrauma
var item = new Item(itemPrefab, pos, sub)
{
ID = itemId
ID = itemId,
SpawnedInOutpost = spawnedInOutpost
};
if (item.body != null)
@@ -105,7 +105,7 @@ namespace Barotrauma
}
else
{
Vector2 placeSize = size;
Vector2 placeSize = size * Scale;
if (placePosition == Vector2.Zero)
{
@@ -161,7 +161,14 @@ namespace Barotrauma
}
else
{
sprite?.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), size, color: SpriteColor);
Vector2 placeSize = size * Scale;
if (placePosition != Vector2.Zero)
{
if (ResizeHorizontal) { placeSize.X = Math.Max(position.X - placePosition.X, placeSize.X); }
if (ResizeVertical) { placeSize.Y = Math.Max(placePosition.Y - position.Y, placeSize.Y); }
position = placePosition;
}
sprite?.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, color: SpriteColor);
}
}
@@ -173,7 +180,15 @@ namespace Barotrauma
}
else
{
if (sprite != null) sprite.DrawTiled(spriteBatch, new Vector2(placeRect.X, -placeRect.Y), placeRect.Size.ToVector2(), null, SpriteColor * 0.8f);
Vector2 position = Submarine.MouseToWorldGrid(Screen.Selected.Cam, Submarine.MainSub);
Vector2 placeSize = size * Scale;
if (placePosition != Vector2.Zero)
{
if (ResizeHorizontal) { placeSize.X = Math.Max(position.X - placePosition.X, placeSize.X); }
if (ResizeVertical) { placeSize.Y = Math.Max(placePosition.Y - position.Y, placeSize.Y); }
position = placePosition;
}
sprite?.DrawTiled(spriteBatch, new Vector2(position.X, -position.Y), placeSize, color: SpriteColor);
}
}
}