Unstable 0.1500.1.0 (BaroDev edition)

This commit is contained in:
Markus Isberg
2021-09-03 21:56:31 +09:00
parent 501e02c026
commit e7b7c1a748
143 changed files with 2928 additions and 1356 deletions
@@ -623,6 +623,7 @@ namespace Barotrauma
bool removeOnDeath = inc.ReadBoolean();
ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath);
}
ch.ExperiencePoints = inc.ReadUInt16();
return ch;
}
@@ -1,10 +1,4 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
namespace Barotrauma
{
partial class AfflictionHusk : Affliction
{
File diff suppressed because it is too large Load Diff
@@ -632,7 +632,7 @@ namespace Barotrauma
RefreshDeformations();
}
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null)
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null, bool disableDeformations = false)
{
float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f;
var spriteParams = Params.GetSprite();
@@ -678,7 +678,7 @@ namespace Barotrauma
if (!hideLimb)
{
var deformSprite = DeformSprite;
if (deformSprite != null)
if (deformSprite != null && !disableDeformations)
{
if (ActiveDeformations.Any())
{
@@ -999,10 +999,12 @@ namespace Barotrauma
}
float textureScale = wearable.InheritTextureScale ? TextureScale : wearable.Scale;
float rotation = -body.DrawRotation - wearable.Rotation * Dir;
wearable.Sprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
new Color((color.R * wearableColor.R) / (255.0f * 255.0f), (color.G * wearableColor.G) / (255.0f * 255.0f), (color.B * wearableColor.B) / (255.0f * 255.0f)) * ((color.A * wearableColor.A) / (255.0f * 255.0f)),
origin, -body.DrawRotation,
origin, rotation,
Scale * textureScale, spriteEffect, depth);
}
@@ -1320,11 +1320,13 @@ namespace Barotrauma
continue;
}
float avgOutCondition = (deconstructItem.OutConditionMin + deconstructItem.OutConditionMax) / 2;
int? deconstructProductPrice = targetItem.GetMinPrice();
if (deconstructProductPrice.HasValue)
{
if (!deconstructProductCost.HasValue) { deconstructProductCost = 0; }
deconstructProductCost += (int)(deconstructProductPrice * deconstructItem.OutCondition);
deconstructProductCost += (int)(deconstructProductPrice * avgOutCondition);
}
if (fabricationRecipe != null)
@@ -1334,9 +1336,9 @@ namespace Barotrauma
{
NewMessage("Deconstructing \"" + itemPrefab.Name + "\" produces \"" + deconstructItem.ItemIdentifier + "\", which isn't required in the fabrication recipe of the item.", Color.Red);
}
else if (ingredient.UseCondition && ingredient.MinCondition < deconstructItem.OutCondition)
else if (ingredient.UseCondition && ingredient.MinCondition < avgOutCondition)
{
NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {targetItem.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(deconstructItem.OutCondition * 100)}%)", Color.Red);
NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {targetItem.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(avgOutCondition * 100)}%)", Color.Red);
}
}
}
@@ -251,6 +251,11 @@ namespace Barotrauma
private readonly bool isHorizontal;
/// <summary>
/// Setting this to true and CanBeFocused to false allows the list background to be unfocusable while the elements can still be interacted with.
/// </summary>
public bool CanInteractWhenUnfocusable { get; set; } = false;
/// <param name="isScrollBarOnDefaultSide">For horizontal listbox, default side is on the bottom. For vertical, it's on the right.</param>
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "", bool isScrollBarOnDefaultSide = true, bool useMouseDownToSelect = false) : base(style, rectT)
{
@@ -570,7 +575,7 @@ namespace Barotrauma
if (child == null || !child.Visible) { continue; }
// selecting
if (Enabled && CanBeFocused && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
if (Enabled && (CanBeFocused || CanInteractWhenUnfocusable) && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
{
child.State = ComponentState.Hover;
@@ -79,14 +79,14 @@ namespace Barotrauma
new Rectangle(
sliderArea.X + (int)sliceBorderSizes.X,
sliderArea.Y,
(int)((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount),
(int)Math.Round((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount),
sliderArea.Height)
:
new Rectangle(
sliderArea.X,
(int)(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W),
(int)Math.Round(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W),
sliderArea.Width,
(int)((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount));
(int)Math.Round((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount));
sliderRect.Width = Math.Max(sliderRect.Width, 1);
sliderRect.Height = Math.Max(sliderRect.Height, 1);
@@ -1219,7 +1219,11 @@ namespace Barotrauma
GUIFrame characterInfoFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.3f), talentInfoLayoutGroup.RectTransform, Anchor.TopLeft), style: null);
GUILayoutGroup characterInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), characterInfoFrame.RectTransform, anchor: Anchor.TopLeft), childAnchor: Anchor.TopLeft, isHorizontal: true);
CreateCharacterSheet(characterInfoColumn);
// move to a different tab menu
if (GameSettings.VerboseLogging)
{
CreateCharacterSheet(characterInfoColumn);
}
if (!TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
@@ -1254,7 +1258,7 @@ namespace Barotrauma
Stretch = true,
};
foreach (Talent talent in talentOption.Talents)
foreach (TalentPrefab talent in talentOption.Talents)
{
int optionPadding = GUI.IntScale(10);
GUIFrame talentFrame = new GUIFrame(new RectTransform(new Point(talentOptionFrame.Rect.Width, talentOptionFrame.Rect.Height - optionPadding), talentOptionLayoutGroup.RectTransform), style: null)
@@ -1269,13 +1273,13 @@ namespace Barotrauma
GUIButton talentButton = new GUIButton(new RectTransform(Vector2.One, talentFrame.RectTransform, anchor: Anchor.Center), style: "TalentFrame")
{
ToolTip = $"{TextManager.Get("talentname." + talent.Identifier, returnNull: true) ?? talent.Identifier} \n\n{TextManager.Get("talentdescription." + talent.Identifier, returnNull: true) ?? string.Empty}",
ToolTip = $"{talent.DisplayName}\n\n{talent.Description}",
UserData = talent.Identifier,
PressedColor = pressedColor,
OnClicked = (button, userData) =>
{
talentTitleText.Text = TextManager.Get("talentname." + talent.Identifier, returnNull: true) ?? string.Empty;
talentDescriptionText.Text = TextManager.Get("talentdescription." + talent.Identifier, returnNull: true) ?? string.Empty;
talentTitleText.Text = talent.DisplayName;
talentDescriptionText.Text = talent.Description;
// deselect other buttons in tier by removing their selected talents from pool
foreach (GUIButton guiButton in talentOptionLayoutGroup.GetAllChildren<GUIButton>())
@@ -1440,10 +1444,10 @@ namespace Barotrauma
private readonly StatTypes[] combatStats = new StatTypes[]
{
StatTypes.MaximumHealthMultiplier,
StatTypes.MovementSpeed,
StatTypes.SwimmingSpeed,
StatTypes.RepairSpeed,
StatTypes.MeleeAttackMultiplier,
StatTypes.MeleeAttackSpeed,
StatTypes.RangedAttackSpeed,
StatTypes.TurretAttackSpeed,
};
private readonly StatTypes[] miscStats = new StatTypes[]
@@ -99,7 +99,9 @@ namespace Barotrauma
crewList = new GUIListBox(new RectTransform(Vector2.One, crewArea.RectTransform), style: null, isScrollBarOnDefaultSide: false)
{
AutoHideScrollBar = false,
CanBeFocused = false,
CanDragElements = true,
CanInteractWhenUnfocusable = true,
OnSelected = (component, userData) => false,
SelectMultiple = false,
Spacing = (int)(GUI.Scale * 10),
@@ -770,7 +772,7 @@ namespace Barotrauma
if (IsSinglePlayer)
{
character.SetOrder(order, option, priority, orderGiver, speak: orderGiver != character);
string message = order?.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority);
string message = order?.GetChatMessage(character.Name, orderGiver?.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority);
orderGiver?.Speak(message);
}
else if (orderGiver != null)
@@ -1905,13 +1907,23 @@ namespace Barotrauma
}
}
private bool CanSomeoneHearCharacter()
private bool CanCharacterBeHeard()
{
#if DEBUG
if (Character.Controlled == null) { return true; }
#endif
return Character.Controlled != null &&
(characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)));
if (Character.Controlled != null)
{
if (characterContext == null)
{
return characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled));
}
else
{
return characterContext.CanHearCharacter(Character.Controlled);
}
}
return false;
}
private Entity FindEntityContext()
@@ -2580,7 +2592,7 @@ namespace Barotrauma
for (int i = 0; i < orders.Count; i++)
{
order = orders[i];
disableNode = !CanSomeoneHearCharacter() ||
disableNode = !CanCharacterBeHeard() ||
(order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) &&
order.GetMatchingItems(true, interactableFor: characterContext ?? Character.Controlled).None());
optionNodes.Add(new Tuple<GUIComponent, Keys>(
@@ -2728,7 +2740,7 @@ namespace Barotrauma
}
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count));
bool disableNode = !CanSomeoneHearCharacter();
bool disableNode = !CanCharacterBeHeard();
for (int i = 0; i < contextualOrders.Count; i++)
{
optionNodes.Add(new Tuple<GUIComponent, Keys>(
@@ -2766,7 +2778,7 @@ namespace Barotrauma
if (checkIfOrderCanBeHeard && !disableNode)
{
disableNode = !CanSomeoneHearCharacter();
disableNode = !CanCharacterBeHeard();
}
var mustSetOptionOrTarget = order.HasOptions;
@@ -2827,7 +2839,7 @@ namespace Barotrauma
if (disableNode)
{
node.CanBeFocused = icon.CanBeFocused = false;
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get("nocharactercanhear"));
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get(characterContext == null ? "nocharactercanhear" : "thischaractercanthear"));
}
else if (hotkey >= 0)
{
@@ -2999,11 +3011,11 @@ namespace Barotrauma
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") +
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip"));
}
if (!CanSomeoneHearCharacter())
if (!CanCharacterBeHeard())
{
node.CanBeFocused = false;
if (icon != null) { icon.CanBeFocused = false; }
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get("nocharactercanhear"));
CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get(characterContext == null ? "nocharactercanhear" : "thischaractercanthear"));
}
else if (hotkey >= 0)
{
@@ -174,6 +174,12 @@ namespace Barotrauma
(int)SlotPositions[i].X,
(int)SlotPositions[i].Y,
(int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier));
if (SlotTypes[i] == InvSlotType.HealthInterface &&
character.CharacterHealth?.InventorySlotContainer != null)
{
slotRect.Width = slotRect.Height = (int)(character.CharacterHealth.InventorySlotContainer.Rect.Width * 1.2f);
}
ItemContainer itemContainer = slots[i].FirstOrDefault()?.GetComponent<ItemContainer>();
if (itemContainer != null)
@@ -238,6 +244,8 @@ namespace Barotrauma
{
if (visualSlots[i].Disabled || (slots[i].HideIfEmpty && slots[i].Empty())) { return true; }
if (CharacterHealth.OpenHealthWindow != Character.Controlled?.CharacterHealth && SlotTypes[i] == InvSlotType.HealthInterface) { return true; }
if (layout == Layout.Default)
{
if (PersonalSlots.HasFlag(SlotTypes[i]) && !personalSlotArea.Contains(visualSlots[i].Rect.Center + visualSlots[i].DrawOffset.ToPoint())) { return true; }
@@ -359,7 +367,7 @@ namespace Barotrauma
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing;
for (int i = 0; i < visualSlots.Length; i++)
{
if (HideSlot(i)) { continue; }
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
if (PersonalSlots.HasFlag(SlotTypes[i]))
{
@@ -383,7 +391,7 @@ namespace Barotrauma
continue;
}
if (HideSlot(i)) { continue; }
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
if (PersonalSlots.HasFlag(SlotTypes[i]))
{
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
@@ -399,7 +407,7 @@ namespace Barotrauma
x = lowerX;
for (int i = 0; i < SlotPositions.Length; i++)
{
if (!HideSlot(i)) { continue; }
if (!HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
x -= visualSlots[i].Rect.Width + Spacing;
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
@@ -414,7 +422,7 @@ namespace Barotrauma
for (int i = 0; i < SlotPositions.Length; i++)
{
if (HideSlot(i)) { continue; }
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; }
if (PersonalSlots.HasFlag(SlotTypes[i]))
{
@@ -436,7 +444,7 @@ namespace Barotrauma
SlotPositions[i] = new Vector2(rightSlot ? handSlotX : handSlotX - visualSlots[0].Rect.Width - Spacing, personalSlotY);
continue;
}
if (!HideSlot(i)) { continue; }
if (!HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
x += visualSlots[i].Rect.Width + Spacing;
}
@@ -450,7 +458,7 @@ namespace Barotrauma
int x = startX, y = startY;
for (int i = 0; i < SlotPositions.Length; i++)
{
if (HideSlot(i)) continue;
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes)
{
SlotPositions[i] = new Vector2(x, y);
@@ -462,7 +470,7 @@ namespace Barotrauma
int n = 0;
for (int i = 0; i < SlotPositions.Length; i++)
{
if (HideSlot(i)) continue;
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes)
{
SlotPositions[i] = new Vector2(x, y);
@@ -479,13 +487,23 @@ namespace Barotrauma
}
break;
}
if (character.CharacterHealth?.UseHealthWindow ?? false)
{
Vector2 pos = character.CharacterHealth.InventorySlotContainer.Rect.Location.ToVector2();
for (int i = 0; i < capacity; i++)
{
if (SlotTypes[i] != InvSlotType.HealthInterface) { continue; }
SlotPositions[i] = pos;
pos.Y += visualSlots[i].Rect.Height + Spacing;
}
}
CreateSlots();
if (layout == Layout.Default)
{
HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
}
}
protected override void ControlInput(Camera cam)
@@ -679,7 +697,7 @@ namespace Barotrauma
if (item != null)
{
var slot = visualSlots[i];
if (item.AllowedSlots.Any(a => a != InvSlotType.Any))
if (item.AllowedSlots.Any(a => a != InvSlotType.Any && a != InvSlotType.HealthInterface))
{
HandleButtonEquipStates(item, slot, deltaTime);
}
@@ -858,7 +876,9 @@ namespace Barotrauma
private QuickUseAction GetQuickUseAction(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment)
{
if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null)
if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null &&
//if the item can be equipped in the health interface slot, don't use it as a treatment but try to equip it
!item.AllowedSlots.Contains(InvSlotType.HealthInterface))
{
return QuickUseAction.UseTreatment;
}
@@ -1153,7 +1173,7 @@ namespace Barotrauma
for (int i = 0; i < capacity; i++)
{
if (HideSlot(i)) { continue; }
if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; }
//don't draw the item if it's being dragged out of the slot
bool drawItem = !DraggingItems.Any() || !slots[i].Items.All(it => DraggingItems.Contains(it)) || visualSlots[i].MouseOn();
@@ -1207,7 +1227,7 @@ namespace Barotrauma
highlightedQuickUseSlot = visualSlots[i];
}
if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any))
if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any) || SlotTypes[i] == InvSlotType.HealthInterface)
{
continue;
}
@@ -0,0 +1,74 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System.Linq;
namespace Barotrauma.Items.Components
{
partial class GeneticMaterial : ItemComponent
{
[Serialize(0.0f, false)]
public float TooltipValueMin { get; set; }
[Serialize(0.0f, false)]
public float TooltipValueMax { get; set; }
public override void AddTooltipInfo(ref string name, ref string description)
{
if (!string.IsNullOrEmpty(materialName))
{
string mergedMaterialName = materialName;
foreach (Item containedItem in item.ContainedItems)
{
var containedMaterial = containedItem.GetComponent<GeneticMaterial>();
if (containedMaterial == null) { continue; }
mergedMaterialName += ", " + containedMaterial.materialName;
}
name = TextManager.GetWithVariable("entityname.geneticmaterial", "[type]", mergedMaterialName);
}
if (Tainted)
{
name = TextManager.GetWithVariable("entityname.taintedgeneticmaterial", "[geneticmaterialname]", name);
}
if (TextManager.ContainsTag("entitydescription."+Item.prefab.Identifier))
{
int value = (int)MathHelper.Lerp(TooltipValueMin, TooltipValueMax, item.ConditionPercentage / 100.0f);
description = TextManager.GetWithVariable("entitydescription." + Item.prefab.Identifier, "[value]", value.ToString());
}
}
public void ModifyDeconstructInfo(Deconstructor deconstructor, ref string buttonText, ref string infoText)
{
if (deconstructor.InputContainer.Inventory.AllItems.Count() == 2)
{
if (!deconstructor.InputContainer.Inventory.AllItems.All(it => it.prefab == item.prefab))
{
buttonText = TextManager.Get("researchstation.combine");
infoText = TextManager.Get("researchstation.combine.infotext");
}
else
{
buttonText = TextManager.Get("researchstation.refine");
int taintedProbability = (int)(GetTaintedProbabilityOnRefine(Character.Controlled) * 100);
infoText = TextManager.GetWithVariable("researchstation.refine.infotext", "[taintedprobability]", taintedProbability.ToString());
}
}
}
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
{
Tainted = msg.ReadBoolean();
if (Tainted)
{
uint selectedTaintedEffectId = msg.ReadUInt32();
selectedTaintedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedTaintedEffectId);
}
else
{
uint selectedEffectId = msg.ReadUInt32();
selectedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedEffectId);
}
}
}
}
@@ -621,6 +621,6 @@ namespace Barotrauma.Items.Components
}
OnResolutionChanged();
}
public virtual void AddTooltipInfo(ref string description) { }
public virtual void AddTooltipInfo(ref string name, ref string description) { }
}
}
@@ -58,6 +58,9 @@ namespace Barotrauma.Items.Components
[Serialize(null, false)]
public string ContainedStateIndicatorStyle { get; set; }
[Serialize(-1, false, description: "Can be used to make the contained state indicator display the condition of the item in a specific slot even when the container's capacity is more than 1.")]
public int ContainedStateIndicatorSlot { get; set; }
[Serialize(true, false, description: "Should an indicator displaying the state of the contained items be displayed on this item's inventory slot. "+
"If this item can only contain one item, the indicator will display the condition of the contained item, otherwise it will indicate how full the item is.")]
public bool ShowContainedStateIndicator { get; set; }
@@ -14,12 +14,19 @@ namespace Barotrauma.Items.Components
}
private GUIButton activateButton;
private GUIComponent inputInventoryHolder, outputInventoryHolder;
private GUICustomComponent inputInventoryOverlay;
private GUIComponent inSufficientPowerWarning;
private bool pendingState;
private GUITextBlock infoArea;
[Serialize("DeconstructorDeconstruct", true)]
public string ActivateButtonText { get; set; }
[Serialize(0.0f, true)]
public float InfoAreaWidth { get; set; }
partial void InitProjSpecific(XElement element)
{
CreateGUI();
@@ -39,6 +46,12 @@ namespace Barotrauma.Items.Components
RelativeSpacing = 0.08f
};
new GUITextBlock(new RectTransform(new Vector2(1f, 0.07f), paddedFrame.RectTransform), item.Name, font: GUI.SubHeadingFont)
{
TextAlignment = Alignment.Center,
AutoScaleHorizontal = true
};
var topFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null);
// === INPUT LABEL === //
@@ -55,22 +68,23 @@ namespace Barotrauma.Items.Components
// === INPUT SLOTS === //
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null);
inputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false };
new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false };
// === ACTIVATE BUTTON === //
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.7f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft);
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft);
activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton")
{
TextBlock = { AutoScaleHorizontal = true },
OnClicked = ToggleActive
};
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform),
TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow", wrap: true)
{
HoverColor = Color.Black,
IgnoreLayoutGroups = true,
Visible = false,
CanBeFocused = false
CanBeFocused = false,
AutoScaleHorizontal = true
};
// === OUTPUT AREA === //
@@ -86,8 +100,62 @@ namespace Barotrauma.Items.Components
outputLabel.RectTransform.Resize(new Point((int) outputLabel.Font.MeasureString(outputLabel.Text).X, outputLabel.RectTransform.Rect.Height));
new GUIFrame(new RectTransform(Vector2.One, outputLabelArea.RectTransform), style: "HorizontalLine");
var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), bottomFrame.RectTransform, Anchor.CenterLeft), childAnchor: Anchor.BottomLeft, isHorizontal: true) { Stretch = true, RelativeSpacing = 0.05f };
// === OUTPUT SLOTS === //
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1f), bottomFrame.RectTransform, Anchor.CenterLeft), style: null);
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f - InfoAreaWidth, 1f), outputArea.RectTransform, Anchor.CenterLeft), style: null);
if (InfoAreaWidth >= 0.0f)
{
var infoAreaContainer = new GUILayoutGroup(new RectTransform(new Vector2(InfoAreaWidth, 0.8f), outputArea.RectTransform), childAnchor: Anchor.CenterLeft);
infoArea = new GUITextBlock(new RectTransform(new Vector2(0.95f, 0.95f), infoAreaContainer.RectTransform), string.Empty, wrap: true);
}
ActivateButton.OnAddedToGUIUpdateList += (GUIComponent component) =>
{
activateButton.Enabled = true;
infoArea.Text = string.Empty;
if (IsActive)
{
activateButton.Text = TextManager.Get("DeconstructorCancel");
return;
}
bool outputsFound = false;
foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: true))
{
outputsFound = true;
if (!string.IsNullOrEmpty(deconstructItem.ActivateButtonText))
{
string buttonText = TextManager.Get(deconstructItem.ActivateButtonText, returnNull: true) ?? deconstructItem.ActivateButtonText;
string infoText = string.Empty;
if (!string.IsNullOrEmpty(deconstructItem.InfoText))
{
infoText = TextManager.Get(deconstructItem.InfoText, returnNull: true) ?? deconstructItem.InfoText;
}
inputItem.GetComponent<GeneticMaterial>()?.ModifyDeconstructInfo(this, ref buttonText, ref infoText);
activateButton.Text = buttonText;
if (infoArea != null)
{
infoArea.Text = infoText;
}
return;
}
}
//no valid outputs found: check if we're missing some required items from the input slots and display a message about it if possible
if (!outputsFound && infoArea != null)
{
foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: false))
{
if (deconstructItem.RequiredOtherItem.Any() && !string.IsNullOrEmpty(deconstructItem.InfoTextOnOtherItemMissing))
{
string missingItemName = TextManager.Get("entityname." + deconstructItem.RequiredOtherItem.First(), returnNull: true);
infoArea.Text = TextManager.GetWithVariable(deconstructItem.InfoTextOnOtherItemMissing, "[itemname]", missingItemName);
}
}
}
activateButton.Enabled = inputContainer.Inventory.AllItems.Any();
activateButton.Text = TextManager.Get(ActivateButtonText);
};
}
public override bool Select(Character character)
@@ -126,14 +194,30 @@ namespace Barotrauma.Items.Components
private void DrawOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
{
overlayComponent.RectTransform.SetAsLastChild();
if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) { return; }
var lastSlot = visualSlots.Last();
GUI.DrawRectangle(spriteBatch,
new Rectangle(
lastSlot.Rect.X, lastSlot.Rect.Y + (int)(lastSlot.Rect.Height * (1.0f - progressState)),
lastSlot.Rect.Width, (int)(lastSlot.Rect.Height * progressState)),
GUI.Style.Green * 0.5f, isFilled: true);
if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) { return; }
if (DeconstructItemsSimultaneously)
{
for (int i = 0; i < InputContainer.Inventory.Capacity; i++)
{
if (InputContainer.Inventory.GetItemAt(i) == null) { continue; }
DrawProgressBar(InputContainer.Inventory.visualSlots[i]);
}
}
else
{
DrawProgressBar(inputContainer.Inventory.visualSlots.Last());
}
void DrawProgressBar(VisualSlot slot)
{
GUI.DrawRectangle(spriteBatch,
new Rectangle(
slot.Rect.X, slot.Rect.Y + (int)(slot.Rect.Height * (1.0f - progressState)),
slot.Rect.Width, (int)(slot.Rect.Height * progressState)),
GUI.Style.Green * 0.5f, isFilled: true);
}
}
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
@@ -403,7 +403,7 @@ namespace Barotrauma.Items.Components
scissorComponent = new GUIScissorComponent(new RectTransform(Vector2.One, submarineContainer.RectTransform, Anchor.Center));
miniMapContainer = new GUIFrame(new RectTransform(Vector2.One, scissorComponent.Content.RectTransform, Anchor.Center), style: null) { CanBeFocused = false };
miniMapFrame = CreateMiniMap(item.Submarine, miniMapContainer, MiniMapSettings.Default, null, out hullStatusComponents);
miniMapFrame = CreateMiniMap(item.Submarine, submarineContainer, MiniMapSettings.Default, null, out hullStatusComponents);
IEnumerable<Item> pointsOfInterest = Item.ItemList.Where(it => it.Submarine == item.Submarine && !it.HiddenInGame && !it.NonInteractable && it.GetComponent<Repairable>() != null);
electricalFrame = CreateMiniMap(item.Submarine, miniMapContainer, new MiniMapSettings(createHullElements: false), pointsOfInterest, out electricalMapComponents);
@@ -458,7 +458,7 @@ namespace Barotrauma.Items.Components
CreateHUD();
}
if (PlayerInput.PrimaryMouseButtonDown())
if (PlayerInput.PrimaryMouseButtonDown() && currentMode != MiniMapMode.HullStatus)
{
if (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn))
{
@@ -466,20 +466,16 @@ namespace Barotrauma.Items.Components
}
}
float newZoom = Zoom;
if (Math.Abs(PlayerInput.ScrollWheelSpeed) > 0 && (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn)))
if (currentMode != MiniMapMode.HullStatus && Math.Abs(PlayerInput.ScrollWheelSpeed) > 0 && (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn)))
{
newZoom = Math.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f * Zoom, minZoom, maxZoom);
float newZoom = Math.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f * Zoom, minZoom, maxZoom);
float distanceScale = newZoom / Zoom;
mapOffset *= distanceScale;
recalculate |= !MathUtils.NearlyEqual(Zoom, newZoom);
Zoom = newZoom;
}
recalculate |= !MathUtils.NearlyEqual(Zoom, newZoom);
Zoom = newZoom;
Vector2 elementScale = new Vector2(Zoom);
if (dragMapStart is { } dragStart)
{
if (dragMap || Vector2.DistanceSquared(dragStart, PlayerInput.MousePosition) > GUI.IntScale(dragTreshold * dragTreshold))
@@ -487,16 +483,11 @@ namespace Barotrauma.Items.Components
mapOffset.X += PlayerInput.MouseSpeed.X;
mapOffset.Y += PlayerInput.MouseSpeed.Y;
recalculate |= PlayerInput.MouseSpeed != Vector2.Zero;
recalculate = true;
dragMap = true;
}
}
var (maxWidth, maxHeight) = miniMapContainer.Rect.Size.ToVector2() / 2f / Zoom;
mapOffset.X = Math.Clamp(mapOffset.X, -maxWidth, maxWidth);
mapOffset.Y = Math.Clamp(mapOffset.Y, -maxHeight, maxHeight);
if (!PlayerInput.PrimaryMouseButtonHeld())
{
dragMapStart = null;
@@ -505,10 +496,15 @@ namespace Barotrauma.Items.Components
if (recalculate)
{
miniMapContainer.RectTransform.LocalScale = elementScale;
miniMapContainer.RectTransform.LocalScale = new Vector2(Zoom);
miniMapContainer.RectTransform.RecalculateChildren(true, true);
miniMapContainer.RectTransform.AbsoluteOffset = mapOffset.ToPoint();
recalculate = false;
var (maxWidth, maxHeight) = miniMapContainer.Rect.Size.ToVector2() / 2f / Zoom;
mapOffset.X = Math.Clamp(mapOffset.X, -maxWidth, maxWidth);
mapOffset.Y = Math.Clamp(mapOffset.Y, -maxHeight, maxHeight);
}
// is there a better way to do this?
@@ -583,6 +579,7 @@ namespace Barotrauma.Items.Components
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
{
// TODO remove
#warning remove
if (currentMode == MiniMapMode.HullCondition)
{
const string wipText = "work in progress";
@@ -757,7 +754,7 @@ namespace Barotrauma.Items.Components
foreach (Item foundItem in foundItems)
{
RelativeEntityRect scaledRect = new RelativeEntityRect(dockedBorders, foundItem.WorldRect);
Vector2 pos = (scaledRect.PositionRelativeTo(parentRect, skipOffset: true) + scaledRect.SizeRelativeTo(parentRect) / 2f) / Zoom;
Vector2 pos = scaledRect.PositionRelativeTo(parentRect, skipOffset: true) + scaledRect.SizeRelativeTo(parentRect) / 2f;
positions.Add(pos);
}
@@ -873,10 +870,14 @@ namespace Barotrauma.Items.Components
string line1 = gapOpenSum > 0.1f ? TextManager.Get("MiniMapHullBreach") : string.Empty;
Color line1Color = GUI.Style.Red;
string line2 = oxygenAmount == null ? TextManager.Get("MiniMapAirQualityUnavailable") : TextManager.AddPunctuation(':', TextManager.Get("MiniMapAirQuality"), +(int)oxygenAmount + " %");
string line2 = oxygenAmount == null ?
TextManager.Get("MiniMapAirQualityUnavailable") :
TextManager.AddPunctuation(':', TextManager.Get("MiniMapAirQuality"), (int)Math.Round(oxygenAmount.Value) + "%");
Color line2Color = oxygenAmount == null ? GUI.Style.Red : Color.Lerp(GUI.Style.Red, Color.LightGreen, (float)oxygenAmount / 100.0f);
string line3 = waterAmount == null ? TextManager.Get("MiniMapWaterLevelUnavailable") : TextManager.AddPunctuation(':', TextManager.Get("MiniMapWaterLevel"), (int)(waterAmount * 100.0f) + " %");
string line3 = waterAmount == null ?
TextManager.Get("MiniMapWaterLevelUnavailable") :
TextManager.AddPunctuation(':', TextManager.Get("MiniMapWaterLevel"), (int)Math.Round(waterAmount.Value * 100.0f) + "%");
Color line3Color = waterAmount == null ? GUI.Style.Red : Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)waterAmount);
SetTooltip(borderComponent.Rect.Center, header, line1, line2, line3, line1Color, line2Color, line3Color);
@@ -958,7 +959,7 @@ namespace Barotrauma.Items.Components
Rectangle parentRect = container.Rect;
if (miniMapFrame is { } miniMap) { parentRect = miniMap.Rect; }
DrawSubmarine(spriteBatch, parentRect);
DrawSubmarine(spriteBatch);
}
if (Voltage < MinVoltage) { return; }
@@ -979,7 +980,7 @@ namespace Barotrauma.Items.Components
Vector2 spriteScale = targetSize / pingCircle.size;
float scale = Math.Min(blipState, maxBlipState / 2f);
float alpha = 1.0f - Math.Clamp((blipState - maxBlipState * 0.25f) * 2f, 0f, 1f);
pingCircle.Draw(spriteBatch, miniMapFrame.Rect.Location.ToVector2() + (blip * Zoom), GUI.Style.Red * alpha, pingCircle.Origin, 0f, spriteScale * scale, SpriteEffects.None);
pingCircle.Draw(spriteBatch, electricalFrame.Rect.Location.ToVector2() + blip * Zoom, GUI.Style.Red * alpha, pingCircle.Origin, 0f, spriteScale * scale, SpriteEffects.None);
}
}
}
@@ -1002,8 +1003,15 @@ namespace Barotrauma.Items.Components
{
RectangleF waterRect = new RectangleF(hullFrame.Rect.X, hullFrame.Rect.Y + hullFrame.Rect.Height * (1.0f - waterAmount), hullFrame.Rect.Width, hullFrame.Rect.Height * waterAmount);
const float width = 1f;
GUI.DrawFilledRectangle(spriteBatch, waterRect, HullWaterColor);
GUI.DrawLine(spriteBatch, waterRect.Location, new Vector2(waterRect.Right, waterRect.Y), HullWaterLineColor);
if (!MathUtils.NearlyEqual(waterAmount, 1.0f))
{
Vector2 offset = new Vector2(0, width);
GUI.DrawLine(spriteBatch, waterRect.Location + offset, new Vector2(waterRect.Right, waterRect.Y) + offset, HullWaterLineColor, width: width);
}
}
}
@@ -1079,7 +1087,7 @@ namespace Barotrauma.Items.Components
submarinePreview = rt;
}
private void DrawSubmarine(SpriteBatch spriteBatch, Rectangle parentRect)
private void DrawSubmarine(SpriteBatch spriteBatch)
{
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
spriteBatch.End();
@@ -1094,7 +1102,8 @@ namespace Barotrauma.Items.Components
Color blueprintBlue = BlueprintBlue * currentMode switch { MiniMapMode.HullStatus => 0.1f, MiniMapMode.ElectricalView => 0.1f, _ => 0.5f };
Vector2 origin = new Vector2(texture.Width / 2f, texture.Height / 2f);
spriteBatch.Draw(texture, parentRect.Center.ToVector2(), null, blueprintBlue, 0f, origin, Zoom, SpriteEffects.None, 0f);
float scale = currentMode == MiniMapMode.HullStatus ? 1.0f : Zoom;
spriteBatch.Draw(texture, miniMapContainer.Center, null, blueprintBlue, 0f, origin, scale, SpriteEffects.None, 0f);
spriteBatch.End();
}
@@ -1281,12 +1290,12 @@ namespace Barotrauma.Items.Components
GUIFrame hullContainer = new GUIFrame(new RectTransform(containerScale * elementPadding, parent.RectTransform, Anchor.Center), style: null);
ImmutableHashSet<Submarine> connectedSubs = sub.GetConnectedSubs().ToImmutableHashSet();
ImmutableHashSet<Hull> hullList = ImmutableHashSet<Hull>.Empty;
ImmutableDictionary<Hull, ImmutableHashSet<Hull>> combinedHulls = ImmutableDictionary<Hull, ImmutableHashSet<Hull>>.Empty;
ImmutableArray<Hull> hullList = ImmutableArray<Hull>.Empty;
ImmutableDictionary<Hull, ImmutableArray<Hull>> combinedHulls = ImmutableDictionary<Hull, ImmutableArray<Hull>>.Empty;
if (settings.CreateHullElements)
{
hullList = Hull.hullList.Where(IsPartofSub).ToImmutableHashSet();
hullList = Hull.hullList.Where(IsPartofSub).ToImmutableArray();
combinedHulls = CombinedHulls(hullList);
}
@@ -1436,7 +1445,7 @@ namespace Barotrauma.Items.Components
}
}
private static ImmutableDictionary<Hull, ImmutableHashSet<Hull>> CombinedHulls(ImmutableHashSet<Hull> hulls)
private static ImmutableDictionary<Hull, ImmutableArray<Hull>> CombinedHulls(ImmutableArray<Hull> hulls)
{
Dictionary<Hull, HashSet<Hull>> combinedHulls = new Dictionary<Hull, HashSet<Hull>>();
@@ -1460,10 +1469,10 @@ namespace Barotrauma.Items.Components
}
}
return combinedHulls.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableHashSet());
return combinedHulls.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableArray());
}
private static MiniMapHullData ConstructHullPolygon(Hull mainHull, ImmutableHashSet<Hull> linkedHulls, GUIComponent parent, RectangleF worldBorders)
private static MiniMapHullData ConstructHullPolygon(Hull mainHull, ImmutableArray<Hull> linkedHulls, GUIComponent parent, RectangleF worldBorders)
{
Rectangle parentRect = parent.Rect;
@@ -1500,6 +1509,8 @@ namespace Barotrauma.Items.Components
hullRefs.Add(hull);
}
hullRefs.Reverse(); // I have no idea why this is required
ImmutableArray<RectangleF> snappedRectangles = ToolBox.SnapRectangles(normalizedRects, treshold: 1);
List<List<Vector2>> polygon = ToolBox.CombineRectanglesIntoShape(snappedRectangles);
@@ -1508,6 +1519,7 @@ namespace Barotrauma.Items.Components
foreach (List<Vector2> list in polygon)
{
// scale down the polygon just a tiny bit
var (polySizeX, polySizeY) = ToolBox.GetPolygonBoundingBoxSize(list);
float sizeX = polySizeX - 1f,
sizeY = polySizeY - 1f;
@@ -0,0 +1,22 @@
using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma.Items.Components
{
partial class RemoteController : ItemComponent
{
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
{
currentTarget?.DrawHUD(spriteBatch, Screen.Selected.Cam, character);
}
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
{
currentTarget?.UpdateHUD(cam, character,deltaTime);
}
public override void AddToGUIUpdateList()
{
currentTarget?.AddToGUIUpdateList();
}
}
}
@@ -54,6 +54,11 @@ namespace Barotrauma.Items.Components
if (wireComponent != null)
{
equippedWire = wireComponent;
var connectedEnd = equippedWire.OtherConnection(null);
if (connectedEnd?.Item.Submarine != null && panel.Item.Submarine != connectedEnd.Item.Submarine)
{
equippedWire = null;
}
}
}
}
@@ -63,11 +63,11 @@ namespace Barotrauma.Items.Components
}
OutputValue = input;
ShowOnDisplay(input);
ShowOnDisplay(input, addToHistory: true);
item.SendSignal(input, "signal_out");
}
partial void ShowOnDisplay(string input, bool addToHistory = true)
partial void ShowOnDisplay(string input, bool addToHistory)
{
if (addToHistory)
{
@@ -39,6 +39,34 @@ namespace Barotrauma.Items.Components
private set;
}
[Serialize(false, false)]
public bool SeeThroughWalls
{
get;
private set;
}
[Serialize(true, false)]
public bool ShowDeadCharacters
{
get;
private set;
}
[Serialize(true, false)]
public bool ShowTexts
{
get;
private set;
}
[Serialize("72,119,72,120", false)]
public Color OverlayColor
{
get;
private set;
}
private readonly List<Character> visibleCharacters = new List<Character>();
private const float UpdateInterval = 0.5f;
@@ -91,12 +119,13 @@ namespace Barotrauma.Items.Components
foreach (Character c in Character.CharacterList)
{
if (c == equipper || !c.Enabled || c.Removed) { continue; }
if (!ShowDeadCharacters && c.IsDead) { continue; }
float dist = Vector2.DistanceSquared(refEntity.WorldPosition, c.WorldPosition);
if (dist < Range * Range)
{
Vector2 diff = c.WorldPosition - refEntity.WorldPosition;
if (Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
if (SeeThroughWalls || Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
{
visibleCharacters.Add(c);
}
@@ -123,27 +152,54 @@ namespace Barotrauma.Items.Components
{
if (character == null) { return; }
GUI.UIGlow.Draw(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight),
Color.LightGreen * 0.5f);
Character closestCharacter = null;
float closestDist = float.PositiveInfinity;
foreach (Character c in visibleCharacters)
if (OverlayColor.A > 0)
{
if (c == character || !c.Enabled || c.Removed) { continue; }
float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition);
if (dist < closestDist)
{
closestCharacter = c;
closestDist = dist;
}
GUI.UIGlow.Draw(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), OverlayColor);
}
if (closestCharacter != null)
if (ShowTexts)
{
float dist = Vector2.Distance(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), closestCharacter.WorldPosition);
DrawCharacterInfo(spriteBatch, closestCharacter, 1.0f - MathHelper.Max((dist - (Range - FadeOutRange)) / FadeOutRange, 0.0f));
Character closestCharacter = null;
float closestDist = float.PositiveInfinity;
foreach (Character c in visibleCharacters)
{
if (c == character || !c.Enabled || c.Removed) { continue; }
float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition);
if (dist < closestDist)
{
closestCharacter = c;
closestDist = dist;
}
}
if (closestCharacter != null)
{
float dist = Vector2.Distance(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), closestCharacter.WorldPosition);
DrawCharacterInfo(spriteBatch, closestCharacter, 1.0f - MathHelper.Max((dist - (Range - FadeOutRange)) / FadeOutRange, 0.0f));
}
}
if (SeeThroughWalls)
{
spriteBatch.End();
GameMain.LightManager.SolidColorEffect.Parameters["color"].SetValue(Color.Red.ToVector4() * (0.35f + (float)Math.Sin(Timing.TotalTime * 1.6f) * 0.05f));
GameMain.LightManager.SolidColorEffect.CurrentTechnique = GameMain.LightManager.SolidColorEffect.Techniques["SolidColorBlur"];
GameMain.LightManager.SolidColorEffect.Parameters["blurDistance"].SetValue(0.03f + (float)Math.Sin(Timing.TotalTime) * 0.01f);
GameMain.LightManager.SolidColorEffect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: Screen.Selected.Cam.Transform, effect: GameMain.LightManager.SolidColorEffect);
foreach (Character c in visibleCharacters)
{
if (c == character || !c.Enabled || c.Removed) { continue; }
foreach (Limb limb in c.AnimController.Limbs)
{
limb.Draw(spriteBatch, Screen.Selected.Cam, disableDeformations: true);
}
}
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
}
}
@@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components
description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ?? afflictionIdentifier}";
}
public override void AddTooltipInfo(ref string description)
public override void AddTooltipInfo(ref string name, ref string description)
{
if (damageModifiers.Any(d => !MathUtils.NearlyEqual(d.DamageMultiplier, 1f)) || SkillModifiers.Any())
{
@@ -297,9 +297,10 @@ namespace Barotrauma
}
}
string name = item.Name;
foreach (ItemComponent component in item.Components)
{
component.AddTooltipInfo(ref description);
component.AddTooltipInfo(ref name, ref description);
}
if (item.Prefab.ShowContentsInTooltip && item.OwnInventory != null)
@@ -315,7 +316,7 @@ namespace Barotrauma
string colorStr = XMLExtensions.ColorToString(!item.AllowStealing ? GUI.Style.Red : Color.White);
toolTip = $"‖color:{colorStr}‖{item.Name}‖color:end‖";
toolTip = $"‖color:{colorStr}‖{name}‖color:end‖";
if (itemsInSlot.All(it => it.NonInteractable || it.NonPlayerTeamInteractable))
{
toolTip += " " + TextManager.Get("connectionlocked");
@@ -719,7 +720,7 @@ namespace Barotrauma
spacing = new Vector2(10 * UIScale, (10 + UnequippedIndicator.size.Y) * UIScale);
}
int columns = (int)Math.Max(Math.Floor(Math.Sqrt(itemCapacity)), 1);
int columns = MathHelper.Clamp((int)Math.Floor(Math.Sqrt(itemCapacity)), 1, container.SlotsPerRow);
while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f)
{
columns++;
@@ -1543,13 +1544,13 @@ namespace Barotrauma
}
else
{
var containedItem = itemContainer.Inventory.slots[0].FirstOrDefault();
containedState = itemContainer.Inventory.Capacity == 1 ?
var containedItem = itemContainer.Inventory.slots[Math.Max(itemContainer.ContainedStateIndicatorSlot, 0)].FirstOrDefault();
containedState = itemContainer.Inventory.Capacity == 1 || itemContainer.ContainedStateIndicatorSlot > -1 ?
(containedItem == null ? 0.0f : containedItem.Condition / containedItem.MaxCondition) :
itemContainer.Inventory.slots.Count(i => !i.Empty()) / (float)itemContainer.Inventory.capacity;
if (containedItem != null && itemContainer.Inventory.Capacity == 1)
{
int maxStackSize = Math.Min(containedItem.Prefab.MaxStackSize, itemContainer.MaxStackSize);
int maxStackSize = Math.Min(containedItem.Prefab.MaxStackSize, itemContainer.GetMaxStackSize(0));
if (maxStackSize > 1)
{
containedState = itemContainer.Inventory.slots[0].ItemCount / (float)maxStackSize;
@@ -1631,7 +1632,7 @@ namespace Barotrauma
int maxStackSize = item.Prefab.MaxStackSize;
if (item.Container != null)
{
maxStackSize = Math.Min(maxStackSize, item.Container.GetComponent<ItemContainer>()?.MaxStackSize ?? maxStackSize);
maxStackSize = Math.Min(maxStackSize, item.Container.GetComponent<ItemContainer>()?.GetMaxStackSize(slotIndex) ?? maxStackSize);
}
if (maxStackSize > 1 && inventory != null)
{
@@ -1194,7 +1194,14 @@ namespace Barotrauma
}
}
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this) { return; }
if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this)
{
if (Character.Controlled.SelectedConstruction?.GetComponent<RemoteController>()?.TargetItem != this &&
!Character.Controlled.HeldItems.Any(it => it.GetComponent<RemoteController>()?.TargetItem == this))
{
return;
}
}
bool needsLayoutUpdate = false;
foreach (ItemComponent ic in activeHUDs)
@@ -423,20 +423,24 @@ namespace Barotrauma
//select wire if both items it's connected to are selected
var selectedItems = SelectedList.Where(e => e is Item).Cast<Item>().ToList();
foreach (Item item in selectedItems)
foreach (Item item in Item.ItemList)
{
if (item.Connections == null) continue;
foreach (Connection c in item.Connections)
{
foreach (Wire w in c.Wires)
{
if (w == null || SelectedList.Contains(w.Item)) continue;
var wire = item.GetComponent<Wire>();
if (wire == null) { continue; }
Item item0 = wire.Connections[0]?.Item;
Item item1 = wire.Connections[1]?.Item;
if (w.OtherConnection(c) != null && SelectedList.Contains(w.OtherConnection(c).Item))
{
SelectedList.Add(w.Item);
}
}
if (item0 == null && item1 != null)
{
item0 = Item.ItemList.Find(it => it.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(wire) ?? false);
}
else if (item0 != null && item1 == null)
{
item1 = Item.ItemList.Find(it => it.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(wire) ?? false);
}
if (item0 != null && item1 != null && SelectedList.Contains(item0) && SelectedList.Contains(item1))
{
SelectedList.Add(item);
}
}
@@ -326,7 +326,7 @@ namespace Barotrauma
depthSortedDamageable.Insert(i, structure);
}
}
foreach (Structure s in depthSortedDamageable)
{
s.DrawDamage(spriteBatch, damageEffect, editing);
@@ -418,8 +418,8 @@ namespace Barotrauma
float scale = 0.9f;
GUIFrame hullContainer = new GUIFrame(new RectTransform(
(parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
parent.RectTransform, Anchor.Center),
(parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
parent.RectTransform, Anchor.Center),
style: null)
{
UserData = "hullcontainer"
@@ -444,9 +444,9 @@ namespace Barotrauma
{
if (!combinedHulls.ContainsKey(hull))
{
combinedHulls.Add(hull, new HashSet<Hull>());
combinedHulls.Add(hull, new HashSet<Hull>());
}
combinedHulls[hull].Add(linkedHull);
}
}
@@ -454,14 +454,14 @@ namespace Barotrauma
foreach (Hull hull in hullList)
{
Vector2 relativeHullPos = new Vector2(
(hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
(hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
(worldBorders.Y - hull.WorldRect.Y) / (float)worldBorders.Height);
Vector2 relativeHullSize = new Vector2(hull.Rect.Width / (float)worldBorders.Width, hull.Rect.Height / (float)worldBorders.Height);
bool hideHull = combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull));
if (hideHull) { continue; }
Color color = Color.DarkCyan * 0.8f;
var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, style: "MiniMapRoom", color: color)
@@ -477,7 +477,7 @@ namespace Barotrauma
MiniMapHullData data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);
Vector2 relativeHullPos = new Vector2(
(data.Bounds.X - worldBorders.X) / worldBorders.Width,
(data.Bounds.X - worldBorders.X) / worldBorders.Width,
(worldBorders.Y - data.Bounds.Y) / worldBorders.Height);
Vector2 relativeHullSize = new Vector2(data.Bounds.Width / worldBorders.Width, data.Bounds.Height / worldBorders.Height);
@@ -507,9 +507,6 @@ namespace Barotrauma
var (parentW, parentH) = hullContainer.Rect.Size.ToVector2();
Vector2 size = new Vector2(rect.Width / parentW, rect.Height / parentH);
// TODO this won't be required if we some day switch RectTransform to use RectangleF
const float padding = 0.001f;
size.X += padding;
size.Y += padding;
Vector2 pos = new Vector2(rect.X / parentW, rect.Y / parentH);
GUIFrame hullFrame = new GUIFrame(new RectTransform(size, hullContainer.RectTransform) { RelativeOffset = pos }, style: "ScanLinesSeamless", color: color)
@@ -586,7 +583,7 @@ namespace Barotrauma
wRect.Y = -wRect.Y;
var (posX, posY) = new Vector2(
(wRect.X - worldBorders.X) / (float)worldBorders.Width,
(wRect.X - worldBorders.X) / (float)worldBorders.Width,
(worldBorders.Y - wRect.Y) / (float)worldBorders.Height);
var (scaleX, scaleY) = new Vector2(wRect.Width / (float)worldBorders.Width, wRect.Height / (float)worldBorders.Height);
@@ -629,7 +626,7 @@ namespace Barotrauma
}
}
if (Info.Type != SubmarineType.OutpostModule ||
if (Info.Type != SubmarineType.OutpostModule ||
(Info.OutpostModuleInfo?.ModuleFlags.Any(f => !f.Equals("hallwayvertical", StringComparison.OrdinalIgnoreCase) && !f.Equals("hallwayhorizontal", StringComparison.OrdinalIgnoreCase)) ?? true))
{
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
@@ -697,7 +694,7 @@ namespace Barotrauma
int wireCount = item.Connections[i].Wires.Count(w => w != null);
if (doorLinks + wireCount > item.Connections[i].MaxWires)
{
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
new string[] { "[doorcount]", "[freeconnectioncount]" },
new string[] { doorLinks.ToString(), (item.Connections[i].MaxWires - wireCount).ToString() }));
break;
@@ -794,7 +791,7 @@ namespace Barotrauma
return SubEditorScreen.SuppressedWarnings.Contains(type);
}
}
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
{
if (type != ServerNetObject.ENTITY_POSITION)
@@ -184,7 +184,7 @@ namespace Barotrauma.Particles
public ParticlePrefab FindPrefab(string prefabName)
{
return Prefabs.Find(p => p.Identifier == prefabName);
return Prefabs.Find(p => p.Identifier.Equals(prefabName, StringComparison.OrdinalIgnoreCase));
}
private void RemoveParticle(int index)
@@ -1366,6 +1366,7 @@ namespace Barotrauma
LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
roundControlsHolder.Children.ForEach(c => c.IgnoreLayoutGroups = !c.Visible);
roundControlsHolder.Children.ForEach(c => c.RectTransform.RelativeSize = Vector2.One);
roundControlsHolder.Recalculate();
ReadyToStartBox.Parent.Visible = !GameMain.Client.GameStarted;
@@ -51,11 +51,16 @@ namespace Barotrauma
}
// ????????
submarine = new Submarine(SubmarineInfo.SavedSubmarines.FirstOrDefault(info => info.Name.Equals("Kastrull", StringComparison.OrdinalIgnoreCase)));
submarine = new Submarine(SubmarineInfo.SavedSubmarines.FirstOrDefault(info => info.Name.Equals("Crescent", StringComparison.OrdinalIgnoreCase)));
miniMapItem = new Item(ItemPrefab.Find(null, "statusmonitor"), Vector2.Zero, submarine);
MiniMap miniMap = miniMapItem.GetComponent<MiniMap>();
miniMap.PowerConsumption = 0;
foreach (var hull in Hull.hullList)
{
hull.WaterVolume = hull.Volume / 2f;
}
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
dummyCharacter.Info.Name = "Galldren";
dummyCharacter.Inventory.CreateSlots();
@@ -1012,7 +1012,8 @@ namespace Barotrauma
Screen.Selected == GameMain.SpriteEditorScreen ||
Screen.Selected == GameMain.SubEditorScreen ||
Screen.Selected == GameMain.EventEditorScreen ||
(Screen.Selected == GameMain.GameScreen && GameMain.GameSession?.GameMode is TestGameMode))
(Screen.Selected == GameMain.GameScreen && GameMain.GameSession?.GameMode is TestGameMode) ||
Screen.Selected == GameMain.NetLobbyScreen)
{
return "editor";
}
@@ -110,14 +110,14 @@ namespace Barotrauma
foreach (StatusEffect statusEffect in successEffects)
{
float duration = statusEffect.Duration;
onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.First), -pair.Second, duration)));
onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration)));
onSuccessAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
}
foreach (StatusEffect statusEffect in failureEffects)
{
float duration = statusEffect.Duration;
onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.First), -pair.Second, duration)));
onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration)));
onFailureAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
}
}