Unstable 1.8.4.0
This commit is contained in:
@@ -6,11 +6,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Controller : ItemComponent
|
||||
{
|
||||
private bool chatBoxOriginalState;
|
||||
private bool isHUDsHidden;
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
base.DrawHUD(spriteBatch, character);
|
||||
if (focusTarget != null && character.ViewTarget == focusTarget)
|
||||
{
|
||||
foreach (ItemComponent ic in focusTarget.Components)
|
||||
@@ -23,48 +23,31 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList(int order = 0)
|
||||
{
|
||||
base.AddToGUIUpdateList(order);
|
||||
if (focusTarget != null && Character.Controlled.ViewTarget == focusTarget)
|
||||
{
|
||||
focusTarget.AddToGUIUpdateList(order);
|
||||
}
|
||||
}
|
||||
|
||||
partial void HideHUDs(bool value)
|
||||
{
|
||||
if (isHUDsHidden == value) { return; }
|
||||
if (value == true)
|
||||
if (value)
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.AutoHideCrewList();
|
||||
ToggleChatBox(false, storeOriginalState: true);
|
||||
ChatBox.AutoHideChatBox();
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.ResetCrewList();
|
||||
ToggleChatBox(chatBoxOriginalState, storeOriginalState: false);
|
||||
GameMain.GameSession?.CrewManager?.ResetCrewListOpenState();
|
||||
ChatBox.ResetChatBoxOpenState();
|
||||
}
|
||||
isHUDsHidden = value;
|
||||
}
|
||||
|
||||
private void ToggleChatBox(bool value, bool storeOriginalState)
|
||||
{
|
||||
var crewManager = GameMain.GameSession?.CrewManager;
|
||||
if (crewManager == null) { return; }
|
||||
|
||||
if (crewManager.IsSinglePlayer)
|
||||
{
|
||||
if (crewManager.ChatBox != null)
|
||||
{
|
||||
if (storeOriginalState)
|
||||
{
|
||||
chatBoxOriginalState = crewManager.ChatBox.ToggleOpen;
|
||||
}
|
||||
crewManager.ChatBox.ToggleOpen = value;
|
||||
}
|
||||
}
|
||||
else if (GameMain.Client != null)
|
||||
{
|
||||
if (storeOriginalState)
|
||||
{
|
||||
chatBoxOriginalState = GameMain.Client.ChatBox.ToggleOpen;
|
||||
}
|
||||
GameMain.Client.ChatBox.ToggleOpen = value;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
public override void CreateEditingHUD(SerializableEntityEditor editor)
|
||||
{
|
||||
|
||||
+17
-8
@@ -154,12 +154,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
infoArea.Text = TextManager.Get(InfoText).Fallback(InfoText);
|
||||
}
|
||||
|
||||
if (IsActive)
|
||||
{
|
||||
activateButton.Text = TextManager.Get("DeconstructorCancel");
|
||||
infoArea.Text = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
bool outputsFound = false;
|
||||
foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: true))
|
||||
{
|
||||
@@ -174,27 +176,34 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
inputItem.GetComponent<GeneticMaterial>()?.ModifyDeconstructInfo(this, ref buttonText, ref infoText);
|
||||
activateButton.Text = buttonText;
|
||||
if (infoArea != null)
|
||||
{
|
||||
infoArea.Text = infoText;
|
||||
}
|
||||
infoArea.Text = infoText;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LocalizedString activateButtonText = TextManager.Get(ActivateButtonText);
|
||||
activateButton.Enabled = outputsFound || !InputContainer.Inventory.IsEmpty();
|
||||
activateButton.Text = activateButtonText;
|
||||
|
||||
//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))
|
||||
{
|
||||
LocalizedString infoText = string.Empty;
|
||||
if (deconstructItem.RequiredOtherItem.Any() && !string.IsNullOrEmpty(deconstructItem.InfoTextOnOtherItemMissing))
|
||||
{
|
||||
LocalizedString missingItemName = TextManager.Get("entityname." + deconstructItem.RequiredOtherItem.First());
|
||||
infoArea.Text = TextManager.GetWithVariable(deconstructItem.InfoTextOnOtherItemMissing, "[itemname]", missingItemName);
|
||||
infoText = TextManager.GetWithVariable(deconstructItem.InfoTextOnOtherItemMissing, "[itemname]", missingItemName);
|
||||
}
|
||||
|
||||
inputItem.GetComponent<GeneticMaterial>()?.ModifyDeconstructInfo(this, ref activateButtonText, ref infoText);
|
||||
|
||||
activateButton.Text = activateButtonText;
|
||||
infoArea.Text = infoText;
|
||||
}
|
||||
}
|
||||
activateButton.Enabled = outputsFound || !InputContainer.Inventory.IsEmpty();
|
||||
activateButton.Text = TextManager.Get(ActivateButtonText);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -415,7 +424,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
|
||||
{
|
||||
inSufficientPowerWarning.Visible = IsActive && !hasPower;
|
||||
inSufficientPowerWarning.Visible = IsActive && !HasPower;
|
||||
}
|
||||
|
||||
private bool OnActivateButtonClicked(GUIButton button, object obj)
|
||||
|
||||
+327
-130
@@ -11,11 +11,21 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Fabricator : Powered, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private enum SortBy
|
||||
{
|
||||
Category,
|
||||
Alphabetical,
|
||||
SkillRequirement,
|
||||
Price
|
||||
}
|
||||
|
||||
private GUIListBox itemList;
|
||||
|
||||
private GUIFrame selectedItemFrame;
|
||||
private GUIFrame selectedItemReqsFrame;
|
||||
|
||||
private GUILayoutGroup outputTopArea, paddedOutputArea;
|
||||
|
||||
private GUITextBlock amountTextMax;
|
||||
private GUIScrollBar amountInput;
|
||||
|
||||
@@ -26,6 +36,8 @@ namespace Barotrauma.Items.Components
|
||||
private GUIButton activateButton;
|
||||
|
||||
private GUITextBox itemFilterBox;
|
||||
private GUITickBox availableOnlyTickBox;
|
||||
private GUIDropDown sortByDropdown;
|
||||
|
||||
private GUIComponent outputSlot;
|
||||
private GUIComponent inputInventoryHolder, outputInventoryHolder;
|
||||
@@ -33,6 +45,9 @@ namespace Barotrauma.Items.Components
|
||||
private readonly List<GUIButton> itemCategoryButtons = new List<GUIButton>();
|
||||
private MapEntityCategory? selectedItemCategory;
|
||||
|
||||
private GUITextBlock requiresRecipeText;
|
||||
private GUITextBlock nothingToShowText;
|
||||
|
||||
public FabricationRecipe SelectedItem
|
||||
{
|
||||
get { return selectedItem; }
|
||||
@@ -65,6 +80,12 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize("vendingmachine.outofstock", IsPropertySaveable.Yes)]
|
||||
public string FabricationLimitReachedText { get; set; }
|
||||
|
||||
[Serialize(true, IsPropertySaveable.No)]
|
||||
public bool ShowSortByDropdown { get; set; }
|
||||
|
||||
[Serialize(true, IsPropertySaveable.No)]
|
||||
public bool ShowAvailableOnlyTickBox { get; set; }
|
||||
|
||||
public override bool RecreateGUIOnResolutionChange => true;
|
||||
|
||||
protected override void OnResolutionChanged()
|
||||
@@ -154,24 +175,24 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
|
||||
// === TOP AREA ===
|
||||
var topFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.65f), mainFrame.RectTransform), style: "InnerFrameDark");
|
||||
var topFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.8f), mainFrame.RectTransform), style: "InnerFrameDark");
|
||||
|
||||
// === ITEM LIST ===
|
||||
var itemListFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), topFrame.RectTransform), childAnchor: Anchor.Center);
|
||||
var paddedItemFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), itemListFrame.RectTransform))
|
||||
var paddedItemFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), itemListFrame.RectTransform), isHorizontal: false)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.03f
|
||||
Stretch = true
|
||||
};
|
||||
var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedItemFrame.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.03f,
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.03f,
|
||||
UserData = "filterarea"
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), filterArea.RectTransform), TextManager.Get("serverlog.filter"), font: GUIStyle.SubHeadingFont)
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1f), filterArea.RectTransform), TextManager.Get("serverlog.filter"),
|
||||
font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true
|
||||
};
|
||||
itemFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), createClearButton: true)
|
||||
@@ -183,29 +204,91 @@ namespace Barotrauma.Items.Components
|
||||
FilterEntities(selectedItemCategory, text);
|
||||
return true;
|
||||
};
|
||||
filterArea.RectTransform.MinSize = new Point(0, itemFilterBox.Rect.Height);
|
||||
filterArea.RectTransform.MaxSize = new Point(int.MaxValue, itemFilterBox.Rect.Height);
|
||||
|
||||
itemList = new GUIListBox(new RectTransform(new Vector2(1f, 0.9f), paddedItemFrame.RectTransform), style: null)
|
||||
var sortByArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedItemFrame.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.03f,
|
||||
Visible = ShowSortByDropdown,
|
||||
IgnoreLayoutGroups = !ShowSortByDropdown
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1f), sortByArea.RectTransform), TextManager.Get("campaignstore.sortby"),
|
||||
font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true
|
||||
};
|
||||
sortByDropdown = new GUIDropDown(new RectTransform(new Vector2(0.8f, 1.0f), sortByArea.RectTransform));
|
||||
foreach (SortBy sortBy in Enum.GetValues<SortBy>())
|
||||
{
|
||||
sortByDropdown.AddItem(TextManager.Get("fabricator.sortby." + sortBy), userData: sortBy);
|
||||
}
|
||||
sortByDropdown.Select(index: 0);
|
||||
sortByDropdown.AfterSelected += (GUIComponent selected, object userdata) =>
|
||||
{
|
||||
FilterEntities(selectedItemCategory, itemFilterBox.Text);
|
||||
SortItems(character: Character.Controlled);
|
||||
return true;
|
||||
};
|
||||
sortByArea.RectTransform.MinSize = new Point(0, sortByDropdown.Rect.Height);
|
||||
sortByArea.RectTransform.MaxSize = new Point(int.MaxValue, sortByDropdown.Rect.Height);
|
||||
|
||||
var availableOnlyTickBoxArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), paddedItemFrame.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
Visible = ShowAvailableOnlyTickBox,
|
||||
IgnoreLayoutGroups = !ShowAvailableOnlyTickBox
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.4f, 1f), availableOnlyTickBoxArea.RectTransform), TextManager.Get("fabricator.onlyshowavailable"),
|
||||
font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true
|
||||
};
|
||||
availableOnlyTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f), availableOnlyTickBoxArea.RectTransform, scaleBasis: ScaleBasis.BothHeight), label: string.Empty)
|
||||
{
|
||||
ToolTip = TextManager.Get("fabricator.onlyshowavailable.tooltip")
|
||||
};
|
||||
availableOnlyTickBox.OnSelected += (tickbox) =>
|
||||
{
|
||||
FilterEntities(selectedItemCategory, itemFilterBox.Text);
|
||||
return true;
|
||||
};
|
||||
availableOnlyTickBox.RectTransform.MinSize = new Point(availableOnlyTickBox.Rect.Height);
|
||||
availableOnlyTickBox.RectTransform.IsFixedSize = true;
|
||||
availableOnlyTickBoxArea.RectTransform.MinSize = new Point(0, availableOnlyTickBox.Rect.Height);
|
||||
availableOnlyTickBoxArea.RectTransform.MaxSize = new Point(int.MaxValue, availableOnlyTickBox.Rect.Height);
|
||||
|
||||
itemList = new GUIListBox(new RectTransform(new Vector2(1f, 0.8f), paddedItemFrame.RectTransform), style: null)
|
||||
{
|
||||
PlaySoundOnSelect = true,
|
||||
OnSelected = (component, userdata) =>
|
||||
{
|
||||
selectedItem = userdata as FabricationRecipe;
|
||||
if (selectedItem != null) { SelectItem(Character.Controlled, selectedItem); }
|
||||
return true;
|
||||
if (userdata is FabricationRecipe fabricationRecipe)
|
||||
{
|
||||
selectedItem = fabricationRecipe;
|
||||
SelectItem(Character.Controlled, selectedItem);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// === SEPARATOR === //
|
||||
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), topFrame.RectTransform, Anchor.Center), style: "VerticalLine");
|
||||
// === SEPARATOR === //
|
||||
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), topFrame.RectTransform, Anchor.Center), style: "VerticalLine");
|
||||
|
||||
// === OUTPUT AREA === //
|
||||
var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1f), topFrame.RectTransform, Anchor.TopRight), childAnchor: Anchor.Center);
|
||||
var paddedOutputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), outputArea.RectTransform));
|
||||
var outputTopArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5F), paddedOutputArea.RectTransform, Anchor.Center), isHorizontal: true);
|
||||
paddedOutputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), outputArea.RectTransform)) { Stretch = true };
|
||||
outputTopArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), paddedOutputArea.RectTransform, Anchor.Center), isHorizontal: true);
|
||||
// === OUTPUT SLOT === //
|
||||
outputSlot = new GUIFrame(new RectTransform(new Vector2(0.4f, 1f), outputTopArea.RectTransform), style: null);
|
||||
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.2f), outputSlot.RectTransform, Anchor.BottomCenter), style: null);
|
||||
outputSlot = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.4f), outputTopArea.RectTransform, scaleBasis: ScaleBasis.BothWidth), style: null);
|
||||
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1.0f), outputSlot.RectTransform, Anchor.BottomCenter), style: null);
|
||||
new GUICustomComponent(new RectTransform(Vector2.One, outputInventoryHolder.RectTransform), DrawOutputOverLay) { CanBeFocused = false };
|
||||
// === DESCRIPTION === //
|
||||
selectedItemFrame = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), outputTopArea.RectTransform), style: null);
|
||||
@@ -213,7 +296,7 @@ namespace Barotrauma.Items.Components
|
||||
selectedItemReqsFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedOutputArea.RectTransform), style: null);
|
||||
|
||||
// === BOTTOM AREA === //
|
||||
var bottomFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.3f), mainFrame.RectTransform), style: null);
|
||||
var bottomFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.2f), mainFrame.RectTransform), style: null);
|
||||
|
||||
if (inputContainer.Capacity > 0)
|
||||
{
|
||||
@@ -298,6 +381,33 @@ namespace Barotrauma.Items.Components
|
||||
CanBeFocused = false
|
||||
};
|
||||
CreateRecipes();
|
||||
|
||||
foreach (MapEntityCategory category in itemCategories)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
|
||||
TextManager.Get("MapEntityCategory." + category), textColor: GUIStyle.TextColorBright)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
UserData = category,
|
||||
Visible = false
|
||||
};
|
||||
}
|
||||
|
||||
requiresRecipeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
|
||||
TextManager.Get("fabricatorrequiresrecipe"), textColor: Color.Red, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
AutoScaleHorizontal = true,
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
nothingToShowText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.8f), itemList.Content.RectTransform), TextManager.Get("noitemsheader"),
|
||||
textAlignment: Alignment.Center, textColor: GUIStyle.TextColorDim)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Visible = false
|
||||
};
|
||||
|
||||
SortItems(character: Character.Controlled);
|
||||
}
|
||||
|
||||
private void RefreshActivateButtonText()
|
||||
@@ -343,7 +453,8 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform), GetRecipeNameAndAmount(fi))
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform),
|
||||
RichString.Rich(GetRecipeNameAndAmount(fi)), font: GUIStyle.SmallFont)
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true,
|
||||
@@ -372,17 +483,17 @@ namespace Barotrauma.Items.Components
|
||||
outputContainer.Inventory.RectTransform = outputInventoryHolder.RectTransform;
|
||||
}
|
||||
|
||||
private static LocalizedString GetRecipeNameAndAmount(FabricationRecipe fabricationRecipe)
|
||||
private static RichString GetRecipeNameAndAmount(FabricationRecipe fabricationRecipe)
|
||||
{
|
||||
if (fabricationRecipe == null) { return ""; }
|
||||
if (fabricationRecipe.Amount > 1)
|
||||
{
|
||||
return TextManager.GetWithVariables("fabricationrecipenamewithamount",
|
||||
("[name]", fabricationRecipe.DisplayName), ("[amount]", fabricationRecipe.Amount.ToString()));
|
||||
("[name]", RichString.Rich(fabricationRecipe.DisplayName)), ("[amount]", fabricationRecipe.Amount.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return fabricationRecipe.DisplayName;
|
||||
return RichString.Rich(fabricationRecipe.DisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,73 +508,106 @@ namespace Barotrauma.Items.Components
|
||||
if (character != Character.Controlled) { return; }
|
||||
|
||||
var nonItems = itemList.Content.Children.Where(c => c.UserData is not FabricationRecipe).ToList();
|
||||
nonItems.ForEach(i => itemList.Content.RemoveChild(i));
|
||||
nonItems.ForEach(i => i.Visible = false);
|
||||
|
||||
SortItems(character: null);
|
||||
FilterEntities(selectedItemCategory, itemFilterBox?.Text ?? string.Empty);
|
||||
HideEmptyItemListCategories();
|
||||
}
|
||||
|
||||
private void SortItems(Character character)
|
||||
{
|
||||
SortBy sortBy = (SortBy)sortByDropdown.SelectedData;
|
||||
|
||||
itemList.Content.RectTransform.SortChildren((c1, c2) =>
|
||||
{
|
||||
var item1 = c1.GUIComponent.UserData as FabricationRecipe;
|
||||
var item2 = c2.GUIComponent.UserData as FabricationRecipe;
|
||||
|
||||
int itemPlacement1 = calculatePlacement(item1);
|
||||
int itemPlacement2 = calculatePlacement(item2);
|
||||
if (itemPlacement1 != itemPlacement2)
|
||||
if (item1 == null && item2 == null)
|
||||
{
|
||||
return itemPlacement1 > itemPlacement2 ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
else if (item1 == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (item2 == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int calculatePlacement(FabricationRecipe recipe)
|
||||
bool missingRecipe1 = MissingRequiredRecipe(item1, character);
|
||||
bool missingRecipe2 = MissingRequiredRecipe(item2, character);
|
||||
if (missingRecipe1 != missingRecipe2)
|
||||
{
|
||||
if (recipe.RequiresRecipe && !AnyOneHasRecipeForItem(character, recipe.TargetItem))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
int placement = FabricationDegreeOfSuccess(character, recipe.RequiredSkills) >= 0.5f ? 0 : -1;
|
||||
return placement;
|
||||
return missingRecipe1.CompareTo(missingRecipe2);
|
||||
}
|
||||
|
||||
return string.Compare(item1.DisplayName.Value, item2.DisplayName.Value);
|
||||
switch (sortBy)
|
||||
{
|
||||
case SortBy.Alphabetical:
|
||||
return string.Compare(item1.DisplayName.Value, item2.DisplayName.Value);
|
||||
case SortBy.Category:
|
||||
var category1 = EnumExtensions.GetIndividualFlags(item1.TargetItem.Category).FirstOrDefault();
|
||||
var category2 = EnumExtensions.GetIndividualFlags(item2.TargetItem.Category).FirstOrDefault();
|
||||
if (category1 == category2)
|
||||
{
|
||||
return string.Compare(item1.DisplayName.Value, item2.DisplayName.Value);
|
||||
}
|
||||
return category1.CompareTo(category2);
|
||||
case SortBy.SkillRequirement:
|
||||
float skillRequirement1 = item1.RequiredSkills.Sum(skill => skill.Level);
|
||||
float skillRequirement2 = item2.RequiredSkills.Sum(skill => skill.Level);
|
||||
if (MathUtils.NearlyEqual(skillRequirement1, skillRequirement2))
|
||||
{
|
||||
return string.Compare(item1.DisplayName.Value, item2.DisplayName.Value);
|
||||
}
|
||||
return skillRequirement1.CompareTo(skillRequirement2);
|
||||
case SortBy.Price:
|
||||
float itemValue1 = item1.TargetItem.DefaultPrice?.Price ?? 0;
|
||||
float itemValue2 = item2.TargetItem.DefaultPrice?.Price ?? 0;
|
||||
if (MathUtils.NearlyEqual(itemValue1, itemValue2))
|
||||
{
|
||||
return string.Compare(item1.DisplayName.Value, item2.DisplayName.Value);
|
||||
}
|
||||
return itemValue2.CompareTo(itemValue1);
|
||||
default:
|
||||
throw new NotImplementedException($"Sorting by {sortBy} has not been implemented.");
|
||||
}
|
||||
});
|
||||
|
||||
var sufficientSkillsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
|
||||
TextManager.Get("fabricatorsufficientskills"), textColor: GUIStyle.Green, font: GUIStyle.SubHeadingFont)
|
||||
if (sortBy == SortBy.Category)
|
||||
{
|
||||
AutoScaleHorizontal = true,
|
||||
CanBeFocused = false
|
||||
};
|
||||
sufficientSkillsText.RectTransform.SetAsFirstChild();
|
||||
foreach (var categoryText in itemList.Content.Children.Where(c => c.UserData?.GetType() == typeof(MapEntityCategory)).ToList())
|
||||
{
|
||||
categoryText.RectTransform.SetAsLastChild();
|
||||
var category = (MapEntityCategory)categoryText.UserData;
|
||||
var firstChildWithMatchingCategory = itemList.Content.Children.FirstOrDefault(c => c.UserData is FabricationRecipe recipe && EnumExtensions.GetIndividualFlags(recipe.TargetItem.Category).FirstOrDefault() == category);
|
||||
if (firstChildWithMatchingCategory != null)
|
||||
{
|
||||
categoryText.RectTransform.RepositionChildInHierarchy(itemList.Content.GetChildIndex(firstChildWithMatchingCategory));
|
||||
categoryText.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryText.Visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var insufficientSkillsText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
|
||||
TextManager.Get("fabricatorinsufficientskills"), textColor: Color.Orange, font: GUIStyle.SubHeadingFont)
|
||||
requiresRecipeText.RectTransform.SetAsLastChild();
|
||||
var firstMissingRecipe = itemList.Content.Children.FirstOrDefault(c => c.UserData is FabricationRecipe recipe && MissingRequiredRecipe(recipe, character));
|
||||
if (firstMissingRecipe != null)
|
||||
{
|
||||
AutoScaleHorizontal = true,
|
||||
CanBeFocused = false
|
||||
};
|
||||
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));
|
||||
requiresRecipeText.RectTransform.RepositionChildInHierarchy(itemList.Content.GetChildIndex(firstMissingRecipe));
|
||||
requiresRecipeText.Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sufficientSkillsText.Visible = insufficientSkillsText.Visible = false;
|
||||
sufficientSkillsText.Enabled = insufficientSkillsText.Enabled = false;
|
||||
requiresRecipeText.Visible = false;
|
||||
}
|
||||
|
||||
var requiresRecipeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), itemList.Content.RectTransform),
|
||||
TextManager.Get("fabricatorrequiresrecipe"), textColor: Color.Red, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
AutoScaleHorizontal = true,
|
||||
CanBeFocused = false
|
||||
};
|
||||
var firstRequiresRecipe = itemList.Content.Children.FirstOrDefault(c =>
|
||||
c.UserData is FabricationRecipe fabricableItem &&
|
||||
fabricableItem.RequiresRecipe && !AnyOneHasRecipeForItem(character, fabricableItem.TargetItem));
|
||||
if (firstRequiresRecipe != null)
|
||||
{
|
||||
requiresRecipeText.RectTransform.RepositionChildInHierarchy(itemList.Content.RectTransform.GetChildIndex(firstRequiresRecipe.RectTransform));
|
||||
}
|
||||
|
||||
FilterEntities(selectedItemCategory, itemFilterBox?.Text ?? string.Empty);
|
||||
HideEmptyItemListCategories();
|
||||
}
|
||||
|
||||
@@ -757,6 +901,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool FilterEntities(MapEntityCategory? category, string filter)
|
||||
{
|
||||
bool onlyShowAvailable = availableOnlyTickBox is { Selected: true };
|
||||
|
||||
bool anyVisible = false;
|
||||
foreach (GUIComponent child in itemList.Content.Children)
|
||||
{
|
||||
FabricationRecipe recipe = child.UserData as FabricationRecipe;
|
||||
@@ -771,16 +918,35 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (recipe.RequiresRecipe && recipe.HideIfNoRecipe)
|
||||
{
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
if (!AnyOneHasRecipeForItem(Character.Controlled, recipe.TargetItem))
|
||||
{
|
||||
child.Visible = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child.Visible =
|
||||
(string.IsNullOrWhiteSpace(filter) || recipe.DisplayName.Contains(filter, StringComparison.OrdinalIgnoreCase)) &&
|
||||
(!category.HasValue || recipe.TargetItem.Category.HasFlag(category.Value));
|
||||
}
|
||||
(!category.HasValue || recipe.TargetItem.Category.HasFlag(category.Value)) &&
|
||||
(!onlyShowAvailable || CanBeFabricated(recipe, availableIngredients, Character.Controlled));
|
||||
if (child.Visible)
|
||||
{
|
||||
anyVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (GUIButton btn in itemCategoryButtons)
|
||||
{
|
||||
btn.Selected = (MapEntityCategory?)btn.UserData == selectedItemCategory;
|
||||
}
|
||||
HideEmptyItemListCategories();
|
||||
nothingToShowText.Visible = !anyVisible;
|
||||
itemList.UserData = "itemlist";
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -788,7 +954,7 @@ namespace Barotrauma.Items.Components
|
||||
private void HideEmptyItemListCategories()
|
||||
{
|
||||
bool visibleElementsChanged = false;
|
||||
//go through the elements backwards, and disable the labels ("insufficient skills to fabricate", "recipe required...") if there's no items below them
|
||||
//go through the elements backwards, and disable the labels if there's no items below them
|
||||
bool recipeVisible = false;
|
||||
foreach (GUIComponent child in itemList.Content.Children.Reverse())
|
||||
{
|
||||
@@ -810,6 +976,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
SortBy sortBy = (SortBy)sortByDropdown.SelectedData;
|
||||
if (sortBy != SortBy.Category)
|
||||
{
|
||||
itemList.Content.Children.Where(c => c.UserData?.GetType() == typeof(MapEntityCategory)).ForEach(c => c.Visible = false);
|
||||
}
|
||||
|
||||
if (visibleElementsChanged)
|
||||
{
|
||||
itemList.UpdateScrollBarSize();
|
||||
@@ -841,8 +1013,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void CreateSelectedItemUI(SelectedRecipe recipe)
|
||||
{
|
||||
var (user, selectedItem, overrideRequiredTime) = recipe;
|
||||
int max = Math.Max(selectedItem.TargetItem.GetMaxStackSize(outputContainer.Inventory) / selectedItem.Amount, 1);
|
||||
var (user, selectedRecipe, overrideRequiredTime) = recipe;
|
||||
int max = Math.Max(selectedRecipe.TargetItem.GetMaxStackSize(outputContainer.Inventory) / selectedRecipe.Amount, 1);
|
||||
|
||||
if (amountInput != null)
|
||||
{
|
||||
@@ -859,18 +1031,59 @@ namespace Barotrauma.Items.Components
|
||||
selectedItemFrame.ClearChildren();
|
||||
selectedItemReqsFrame.ClearChildren();
|
||||
|
||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
|
||||
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f, CanBeFocused = true };
|
||||
var paddedReqFrame = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.9f), selectedItemReqsFrame.RectTransform, Anchor.Center)) { RelativeSpacing = 0.03f };
|
||||
|
||||
LocalizedString itemName = GetRecipeNameAndAmount(selectedItem);
|
||||
LocalizedString itemName = GetRecipeNameAndAmount(selectedRecipe);
|
||||
LocalizedString name = itemName;
|
||||
|
||||
QualityResult result = GetFabricatedItemQuality(selectedItem, user);
|
||||
QualityResult result = GetFabricatedItemQuality(selectedRecipe, user);
|
||||
|
||||
float quality = selectedItem.Quality ?? result.Quality;
|
||||
if (quality > 0 || result.HasRandomQualityRollChance)
|
||||
float minimumQuality = selectedRecipe.Quality ?? result.Quality;
|
||||
|
||||
LocalizedString qualityTooltip = string.Empty;
|
||||
if (result.HasRandomQualityRollChance)
|
||||
{
|
||||
name = TextManager.GetWithVariable("itemname.quality" + (int)quality, "[itemname]", itemName + '\n')
|
||||
float plusOnePercentage = result.TotalPlusOnePercentage;
|
||||
float plusTwoPercentage = result.TotalPlusTwoPercentage;
|
||||
|
||||
string plusOnePercentageText = plusOnePercentage.ToString("F1", CultureInfo.InvariantCulture);
|
||||
string plusTwoPercentageText = plusTwoPercentage.ToString("F1", CultureInfo.InvariantCulture);
|
||||
|
||||
int plusOneQuality = Math.Clamp(result.Quality + 1, min: 0, max: 3);
|
||||
int plusTwoQuality = Math.Clamp(result.Quality + 2, min: 0, max: 3);
|
||||
|
||||
LocalizedString plusOneQualityText = TextManager.Get($"quality{plusOneQuality}");
|
||||
LocalizedString plusTwoQualityText = TextManager.Get($"quality{plusTwoQuality}");
|
||||
|
||||
string localizationTag = plusTwoPercentage > 0f && plusOnePercentage > 0 && plusOneQuality != plusTwoQuality ? "meetsbonusrequirementtwice" : "meetsbonusrequirement";
|
||||
|
||||
var variables = new (string Key, LocalizedString Value)[]
|
||||
{
|
||||
("[chance]", plusOnePercentageText), ("[quality]", plusOneQualityText),
|
||||
("[chance2]", plusTwoPercentageText), ("[quality2]", plusTwoQualityText)
|
||||
};
|
||||
|
||||
if (MathUtils.NearlyEqual(plusOnePercentage, 0))
|
||||
{
|
||||
variables = new[] { ("[chance]", plusTwoPercentageText), ("[quality]", plusTwoQualityText) };
|
||||
}
|
||||
|
||||
if (plusOneQuality == plusTwoQuality)
|
||||
{
|
||||
LocalizedString rawPercentage = result.PlusOnePercentage.ToString("F1", CultureInfo.InvariantCulture);
|
||||
variables = new[] { ("[chance]", rawPercentage), ("[quality]", plusOneQualityText) };
|
||||
}
|
||||
|
||||
if (plusOnePercentage >= 100.0f) { minimumQuality = plusOneQuality; }
|
||||
if (plusTwoPercentage >= 100.0f) { minimumQuality = plusTwoQuality; }
|
||||
|
||||
qualityTooltip = TextManager.GetWithVariables(localizationTag, variables);
|
||||
}
|
||||
|
||||
if (minimumQuality > 0 || result.HasRandomQualityRollChance)
|
||||
{
|
||||
name = TextManager.GetWithVariable("itemname.quality" + (int)minimumQuality, "[itemname]", itemName + '\n')
|
||||
.Fallback(TextManager.GetWithVariable("itemname.quality3", "[itemname]", itemName + '\n'));
|
||||
}
|
||||
|
||||
@@ -884,44 +1097,13 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
var iconLayout = new GUIFrame(new RectTransform(new Vector2(0.4f, 1f), selectedItemFrame.RectTransform, anchor: Anchor.TopRight), style: null);
|
||||
var icon = GameSession.CreateNotificationIcon(iconLayout, offset: true);
|
||||
|
||||
float percentage1 = result.TotalPlusOnePercentage;
|
||||
float percentage2 = result.TotalPlusTwoPercentage;
|
||||
|
||||
string chance1text = percentage1.ToString("F1", CultureInfo.InvariantCulture);
|
||||
string chance2text = percentage2.ToString("F1", CultureInfo.InvariantCulture);
|
||||
|
||||
int quality1 = Math.Clamp(result.Quality + 1, min: 0, max: 3);
|
||||
int quality2 = Math.Clamp(result.Quality + 2, min: 0, max: 3);
|
||||
|
||||
LocalizedString quality1Text = TextManager.Get($"quality{quality1}");
|
||||
LocalizedString quality2Text = TextManager.Get($"quality{quality2}");
|
||||
|
||||
string localizationTag = percentage2 > 0f && percentage1 > 0 && quality1 != quality2 ? "meetsbonusrequirementtwice" : "meetsbonusrequirement";
|
||||
|
||||
var variables = new (string Key, LocalizedString Value)[]
|
||||
{
|
||||
("[chance]", chance1text), ("[quality]", quality1Text),
|
||||
("[chance2]", chance2text), ("[quality2]", quality2Text)
|
||||
};
|
||||
|
||||
if (MathUtils.NearlyEqual(percentage1, 0))
|
||||
{
|
||||
variables = new[] { ("[chance]", chance2text), ("[quality]", quality2Text) };
|
||||
}
|
||||
|
||||
if (quality1 == quality2)
|
||||
{
|
||||
LocalizedString rawPercentage = result.PlusOnePercentage.ToString("F1", CultureInfo.InvariantCulture);
|
||||
variables = new[] { ("[chance]", rawPercentage), ("[quality]", quality1Text) };
|
||||
}
|
||||
|
||||
LocalizedString qualityTooltip = TextManager.GetWithVariables(localizationTag, variables);
|
||||
|
||||
icon.ToolTip = RichString.Rich(qualityTooltip);
|
||||
icon.Visible = icon.CanBeFocused = true;
|
||||
}
|
||||
|
||||
outputTopArea.RectTransform.MaxSize = new Point(int.MaxValue, outputInventoryHolder.Rect.Height);
|
||||
paddedOutputArea.Recalculate();
|
||||
|
||||
nameBlock.Padding = new Vector4(0, nameBlock.Padding.Y, GUI.IntScale(5), nameBlock.Padding.W);
|
||||
if (nameBlock.TextScale < 0.7f)
|
||||
{
|
||||
@@ -932,31 +1114,41 @@ namespace Barotrauma.Items.Components
|
||||
nameBlock.RectTransform.MinSize = new Point(0, (int)(nameBlock.TextSize.Y * nameBlock.TextScale));
|
||||
}
|
||||
|
||||
if (!selectedItem.TargetItem.Description.IsNullOrEmpty())
|
||||
bool largeUI = GuiFrame.Rect.Height > GUI.IntScale(500);
|
||||
if (largeUI)
|
||||
{
|
||||
var description = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform),
|
||||
RichString.Rich(selectedItem.TargetItem.Description),
|
||||
font: GUIStyle.SmallFont, wrap: true);
|
||||
description.Padding = new Vector4(0, description.Padding.Y, description.Padding.Z, description.Padding.W);
|
||||
paddedFrame.ChildAnchor = Anchor.CenterLeft;
|
||||
}
|
||||
|
||||
while (description.Rect.Height + nameBlock.Rect.Height > paddedFrame.Rect.Height)
|
||||
if (!selectedRecipe.TargetItem.Description.IsNullOrEmpty())
|
||||
{
|
||||
var descriptionParent = largeUI ? paddedReqFrame : paddedFrame;
|
||||
var description = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), descriptionParent.RectTransform),
|
||||
RichString.Rich(selectedRecipe.TargetItem.Description),
|
||||
font: GUIStyle.SmallFont, wrap: true);
|
||||
if (!largeUI)
|
||||
{
|
||||
description.Padding = new Vector4(0, description.Padding.Y, description.Padding.Z, description.Padding.W);
|
||||
}
|
||||
|
||||
while (description.Rect.Height + nameBlock.Rect.Height > descriptionParent.Rect.Height)
|
||||
{
|
||||
var lines = description.WrappedText.Split('\n');
|
||||
if (lines.Count <= 1) { break; }
|
||||
var newString = string.Join('\n', lines.Take(lines.Count - 1));
|
||||
description.Text = newString.Substring(0, newString.Length - 4) + "...";
|
||||
description.CalculateHeightFromText();
|
||||
description.ToolTip = selectedItem.TargetItem.Description;
|
||||
description.ToolTip = selectedRecipe.TargetItem.Description;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<Skill> inadequateSkills = Enumerable.Empty<Skill>();
|
||||
if (user != null)
|
||||
{
|
||||
inadequateSkills = selectedItem.RequiredSkills.Where(skill => user.GetSkillLevel(skill.Identifier) < Math.Round(skill.Level * SkillRequirementMultiplier));
|
||||
inadequateSkills = selectedRecipe.RequiredSkills.Where(skill => user.GetSkillLevel(skill.Identifier) < Math.Round(skill.Level * SkillRequirementMultiplier));
|
||||
}
|
||||
|
||||
if (selectedItem.RequiredSkills.Any())
|
||||
if (selectedRecipe.RequiredSkills.Any())
|
||||
{
|
||||
LocalizedString text = "";
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform),
|
||||
@@ -965,20 +1157,20 @@ namespace Barotrauma.Items.Components
|
||||
AutoScaleHorizontal = true,
|
||||
ToolTip = TextManager.Get("fabricatorrequiredskills.tooltip")
|
||||
};
|
||||
foreach (Skill skill in selectedItem.RequiredSkills)
|
||||
foreach (Skill skill in selectedRecipe.RequiredSkills)
|
||||
{
|
||||
text += TextManager.Get("SkillName." + skill.Identifier) + " " + TextManager.Get("Lvl").ToLower() + " " + Math.Round(skill.Level * SkillRequirementMultiplier);
|
||||
if (skill != selectedItem.RequiredSkills.Last()) { text += "\n"; }
|
||||
if (skill != selectedRecipe.RequiredSkills.Last()) { text += "\n"; }
|
||||
}
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), text, font: GUIStyle.SmallFont);
|
||||
}
|
||||
|
||||
float degreeOfSuccess = user == null ? 0.0f : FabricationDegreeOfSuccess(user, selectedItem.RequiredSkills);
|
||||
float degreeOfSuccess = user == null ? 0.0f : FabricationDegreeOfSuccess(user, selectedRecipe.RequiredSkills);
|
||||
if (degreeOfSuccess > 0.5f) { degreeOfSuccess = 1.0f; }
|
||||
|
||||
float requiredTime = overrideRequiredTime.TryUnwrap(out var time)
|
||||
? time
|
||||
: (user == null ? selectedItem.RequiredTime : GetRequiredTime(selectedItem, user));
|
||||
: (user == null ? selectedRecipe.RequiredTime : GetRequiredTime(selectedRecipe, user));
|
||||
|
||||
if ((int)requiredTime > 0)
|
||||
{
|
||||
@@ -991,7 +1183,7 @@ namespace Barotrauma.Items.Components
|
||||
font: GUIStyle.SmallFont);
|
||||
}
|
||||
|
||||
if (SelectedItem.RequiredMoney > 0)
|
||||
if (selectedRecipe.RequiredMoney > 0)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform),
|
||||
TextManager.Get("subeditor.price"), textColor: ToolBox.GradientLerp(degreeOfSuccess, GUIStyle.Red, Color.Yellow, GUIStyle.Green), font: GUIStyle.SubHeadingFont)
|
||||
@@ -1000,7 +1192,6 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), TextManager.FormatCurrency(SelectedItem.RequiredMoney),
|
||||
font: GUIStyle.SmallFont);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1031,7 +1222,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (selectedItem == null) { return false; }
|
||||
if (fabricatedItem == null &&
|
||||
!outputContainer.Inventory.CanBePut(selectedItem.TargetItem, selectedItem.OutCondition * selectedItem.TargetItem.Health))
|
||||
!outputContainer.Inventory.CanProbablyBePut(selectedItem.TargetItem, selectedItem.OutCondition * selectedItem.TargetItem.Health))
|
||||
{
|
||||
outputSlot.Flash(GUIStyle.Red);
|
||||
return false;
|
||||
@@ -1101,8 +1292,14 @@ namespace Barotrauma.Items.Components
|
||||
activateButton.Enabled = canBeFabricated;
|
||||
}
|
||||
|
||||
bool sufficientSkills = FabricationDegreeOfSuccess(character, recipe.RequiredSkills) >= 0.5f;
|
||||
|
||||
Color baseColor = MissingRequiredRecipe(recipe, character) ?
|
||||
GUIStyle.Red :
|
||||
(sufficientSkills ? GUIStyle.TextColorNormal : GUIStyle.Orange);
|
||||
|
||||
var childContainer = child.GetChild<GUILayoutGroup>();
|
||||
childContainer.GetChild<GUITextBlock>().TextColor = Color.White * (canBeFabricated ? 1.0f : 0.5f);
|
||||
childContainer.GetChild<GUITextBlock>().TextColor = baseColor * (canBeFabricated ? 1.0f : 0.5f);
|
||||
childContainer.GetChild<GUIImage>().Color = recipe.TargetItem.InventoryIconColor * (canBeFabricated ? 1.0f : 0.5f);
|
||||
|
||||
var limitReachedText = child.FindChild(nameof(FabricationLimitReachedText));
|
||||
|
||||
@@ -10,45 +10,27 @@ using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
internal readonly struct MiniMapGUIComponent
|
||||
internal readonly record struct MiniMapGUIComponent(GUIComponent RectComponent, GUIComponent BorderComponent)
|
||||
{
|
||||
public readonly GUIComponent RectComponent;
|
||||
public readonly GUIComponent BorderComponent;
|
||||
|
||||
public MiniMapGUIComponent(GUIComponent rectComponent)
|
||||
public MiniMapGUIComponent(GUIComponent rectComponent) : this(rectComponent, rectComponent)
|
||||
{
|
||||
RectComponent = rectComponent;
|
||||
BorderComponent = rectComponent;
|
||||
}
|
||||
|
||||
public MiniMapGUIComponent(GUIComponent frame, GUIComponent linkedHullComponent)
|
||||
{
|
||||
RectComponent = frame;
|
||||
BorderComponent = linkedHullComponent;
|
||||
}
|
||||
|
||||
|
||||
public void Deconstruct(out GUIComponent component, out GUIComponent borderComponent)
|
||||
{
|
||||
component = RectComponent;
|
||||
borderComponent = BorderComponent;
|
||||
}
|
||||
}
|
||||
|
||||
internal readonly struct MiniMapSprite
|
||||
|
||||
internal readonly record struct MiniMapSprite(Sprite? Sprite, Color Color)
|
||||
{
|
||||
public readonly Sprite? Sprite;
|
||||
public readonly Color Color;
|
||||
|
||||
public MiniMapSprite(JobPrefab prefab)
|
||||
public MiniMapSprite(JobPrefab prefab) : this(prefab.IconSmall, prefab.UIColor)
|
||||
{
|
||||
Sprite = prefab.IconSmall;
|
||||
Color = prefab.UIColor;
|
||||
}
|
||||
|
||||
public MiniMapSprite(Order order)
|
||||
|
||||
public MiniMapSprite(Order order) : this(order.SymbolSprite, order.Color)
|
||||
{
|
||||
Sprite = order.SymbolSprite;
|
||||
Color = order.Color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +205,27 @@ namespace Barotrauma.Items.Components
|
||||
NoPowerColor = MiniMapBaseColor * 0.1f,
|
||||
ElectricalBaseColor = GUIStyle.Orange,
|
||||
NoPowerElectricalColor = ElectricalBaseColor * 0.1f;
|
||||
|
||||
|
||||
// If this is portable, only allow displaying data in the player sub (not enemy subs, ruins, wrecks or other unknown places)
|
||||
private bool IsPortableItemAllowed
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsUsableOutsidePlayerSub) { return true; }
|
||||
if (item.Submarine == null) { return false; }
|
||||
if (item.GetComponent<Pickable>() is not Pickable handheldItem) { return true; }
|
||||
// This will effectively make sure wherever we are, it belongs to the player
|
||||
return handheldItem.Picker?.TeamID == item.Submarine.TeamID;
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No, description: "If this item is portable, should it be usable outside the player submarine?")]
|
||||
public bool IsUsableOutsidePlayerSub
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
hullDatas = new Dictionary<Hull, HullData>();
|
||||
@@ -425,22 +427,25 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool VisibleOnItemFinder(Item it)
|
||||
private bool VisibleOnItemFinder(Item targetItem)
|
||||
{
|
||||
if (it?.Submarine == null) { return false; }
|
||||
if (item.Submarine == null || !item.Submarine.IsEntityFoundOnThisSub(it, includingConnectedSubs: true)) { return false; }
|
||||
if (it.NonInteractable || it.IsHidden) { return false; }
|
||||
if (it.GetComponent<Pickable>() == null) { return false; }
|
||||
if (targetItem?.Submarine == null || item.Submarine == null) { return false; }
|
||||
|
||||
var holdable = it.GetComponent<Holdable>();
|
||||
if (!IsPortableItemAllowed) { return false; }
|
||||
|
||||
if (!item.Submarine.IsEntityFoundOnThisSub(targetItem, includingConnectedSubs: true)) { return false; }
|
||||
if (targetItem.NonInteractable || targetItem.IsHidden) { return false; }
|
||||
if (targetItem.GetComponent<Pickable>() == null) { return false; }
|
||||
|
||||
var holdable = targetItem.GetComponent<Holdable>();
|
||||
if (holdable != null && holdable.Attached) { return false; }
|
||||
|
||||
var wire = it.GetComponent<Wire>();
|
||||
var wire = targetItem.GetComponent<Wire>();
|
||||
if (wire != null && wire.Connections.Any(c => c != null)) { return false; }
|
||||
|
||||
if (it.Container?.GetComponent<ItemContainer>() is { DrawInventory: false } or { AllowAccess: false }) { return false; }
|
||||
if (targetItem.Container?.GetComponent<ItemContainer>() is { DrawInventory: false } or { AllowAccess: false }) { return false; }
|
||||
|
||||
if (it.HasTag(Tags.TraitorMissionItem)) { return false; }
|
||||
if (targetItem.HasTag(Tags.TraitorMissionItem)) { return false; }
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -454,18 +459,24 @@ namespace Barotrauma.Items.Components
|
||||
searchAutoComplete?.AddToGUIUpdateList(order: order + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateHUD()
|
||||
|
||||
private void ClearHUD()
|
||||
{
|
||||
subEntities.Clear();
|
||||
prevResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
submarineContainer.ClearChildren();
|
||||
displayedSubs.Clear();
|
||||
}
|
||||
|
||||
if (item.Submarine is null)
|
||||
private void RefreshHUD()
|
||||
{
|
||||
ClearHUD();
|
||||
|
||||
if (item.Submarine is null || !IsPortableItemAllowed)
|
||||
{
|
||||
displayedSubs.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
prevResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
|
||||
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 };
|
||||
@@ -574,18 +585,25 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void UpdateHUDComponentSpecific(Character character, float deltaTime, Camera cam)
|
||||
{
|
||||
//recreate HUD if the subs we should display have changed
|
||||
if (item.Submarine == null && displayedSubs.Count > 0 || // item not inside a sub anymore, but display is still showing subs
|
||||
// Refresh HUD (including possibly just clearing it away) if the subs we should display have changed
|
||||
if (item.Submarine == null && displayedSubs.Count > 0 || // item not inside a sub anymore, but display is still showing subs
|
||||
item.Submarine is { } itemSub &&
|
||||
(
|
||||
!displayedSubs.Contains(itemSub) || // current sub not displayed
|
||||
itemSub.DockedTo.Where(s => s.TeamID == item.Submarine.TeamID).Any(s => !displayedSubs.Contains(s) && itemSub.ConnectedDockingPorts[s].IsLocked) || // some of the docked subs not displayed
|
||||
displayedSubs.Any(s => s != itemSub && !itemSub.DockedTo.Contains(s)) // displaying a sub that shouldn't be displayed
|
||||
// current sub not displayed
|
||||
!displayedSubs.Contains(itemSub) ||
|
||||
// some of the docked subs not displayed
|
||||
itemSub.DockedTo.Where(s => s.TeamID == item.Submarine.TeamID).Any(s => !displayedSubs.Contains(s) && itemSub.ConnectedDockingPorts[s].IsLocked) ||
|
||||
// displaying a sub that shouldn't be displayed
|
||||
displayedSubs.Any(s => s != itemSub && !itemSub.DockedTo.Contains(s))
|
||||
) ||
|
||||
prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight || // resolution changed
|
||||
!submarineContainer.Children.Any()) // We lack a GUI
|
||||
// If this item is portable and not in a player sub and using it otherwise is disallowed
|
||||
!IsPortableItemAllowed ||
|
||||
// resolution changed
|
||||
prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight ||
|
||||
// We lack a GUI
|
||||
!submarineContainer.Children.Any())
|
||||
{
|
||||
CreateHUD();
|
||||
RefreshHUD();
|
||||
}
|
||||
|
||||
//reset data if we haven't received anything in a while
|
||||
@@ -737,7 +755,7 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
if (Voltage < MinVoltage)
|
||||
if (!HasPower)
|
||||
{
|
||||
Vector2 textSize = GUIStyle.Font.MeasureString(noPowerTip);
|
||||
Vector2 textPos = GuiFrame.Rect.Center.ToVector2();
|
||||
@@ -747,7 +765,7 @@ namespace Barotrauma.Items.Components
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMode == MiniMapMode.HullStatus && item.Submarine != null)
|
||||
if (currentMode == MiniMapMode.HullStatus && item.Submarine != null && IsPortableItemAllowed)
|
||||
{
|
||||
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
||||
spriteBatch.End();
|
||||
@@ -958,19 +976,19 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
MiniMapBlips = positions.ToImmutableHashSet();
|
||||
|
||||
if (searchAutoComplete is null) { return; }
|
||||
searchAutoComplete.Visible = false;
|
||||
HideGUIComponent(searchAutoComplete);
|
||||
}
|
||||
|
||||
private void UpdateHUDBack()
|
||||
{
|
||||
if (item.Submarine == null) { return; }
|
||||
|
||||
if (hullInfoFrame != null) { hullInfoFrame.Visible = false; }
|
||||
reportFrame.Visible = false;
|
||||
searchBarFrame.Visible = false;
|
||||
electricalFrame.Visible = false;
|
||||
miniMapFrame.Visible = false;
|
||||
// Clear up mode-specific elements before checking if drawing should continue, so they'll be gone if not
|
||||
HideModeSpecificFrames();
|
||||
|
||||
if (item.Submarine == null || !IsPortableItemAllowed)
|
||||
{
|
||||
ClearHUD();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (currentMode)
|
||||
{
|
||||
@@ -988,7 +1006,24 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void HideModeSpecificFrames()
|
||||
{
|
||||
HideGUIComponent(hullInfoFrame);
|
||||
HideGUIComponent(reportFrame);
|
||||
HideGUIComponent(searchBarFrame);
|
||||
HideGUIComponent(electricalFrame);
|
||||
HideGUIComponent(miniMapFrame);
|
||||
}
|
||||
|
||||
private static void HideGUIComponent(GUIComponent? component)
|
||||
{
|
||||
if (component != null)
|
||||
{
|
||||
component.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateHullStatus()
|
||||
{
|
||||
bool canHoverOverHull = true;
|
||||
@@ -1007,7 +1042,7 @@ namespace Barotrauma.Items.Components
|
||||
child.Color = child.OutlineColor = NoPowerDoorColor;
|
||||
}
|
||||
|
||||
if (Voltage < MinVoltage) { continue; }
|
||||
if (!HasPower) { continue; }
|
||||
|
||||
child.Color = child.OutlineColor = DoorIndicatorColor;
|
||||
if (GUI.MouseOn == child)
|
||||
@@ -1037,7 +1072,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (Voltage < MinVoltage) { continue; }
|
||||
if (!HasPower) { continue; }
|
||||
|
||||
hullDatas.TryGetValue(hull, out HullData? hullData);
|
||||
if (hullData is null)
|
||||
@@ -1187,7 +1222,7 @@ namespace Barotrauma.Items.Components
|
||||
component.Color = component.OutlineColor = NoPowerElectricalColor;
|
||||
}
|
||||
|
||||
if (Voltage < MinVoltage || !miniMapGuiComponent.RectComponent.Visible) { continue; }
|
||||
if (!HasPower || !miniMapGuiComponent.RectComponent.Visible) { continue; }
|
||||
|
||||
int durability = (int)(it.Condition / (it.MaxCondition / it.MaxRepairConditionMultiplier) * 100f);
|
||||
Color color = ToolBox.GradientLerp(durability / 100f, GUIStyle.Red, GUIStyle.Orange, GUIStyle.Green, GUIStyle.Green);
|
||||
@@ -1229,11 +1264,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void DrawHUDBack(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
if (item.Submarine == null) { return; }
|
||||
if (item.Submarine == null || !IsPortableItemAllowed) { return; }
|
||||
|
||||
DrawSubmarine(spriteBatch);
|
||||
DrawSubmarine(spriteBatch);
|
||||
|
||||
if (Voltage < MinVoltage) { return; }
|
||||
if (!HasPower) { return; }
|
||||
Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle;
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||
|
||||
@@ -475,11 +475,8 @@ namespace Barotrauma.Items.Components
|
||||
if (sound != null)
|
||||
{
|
||||
SoundPlayer.PlaySound(
|
||||
sound.Sound,
|
||||
sound,
|
||||
item.WorldPosition,
|
||||
sound.Volume,
|
||||
sound.Range,
|
||||
freqMult: sound.GetRandomFrequencyMultiplier(),
|
||||
hullGuess: item.CurrentHull);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ namespace Barotrauma.Items.Components
|
||||
private bool isConnectedToSteering;
|
||||
|
||||
private static LocalizedString caveLabel;
|
||||
private static LocalizedString enemyLabel;
|
||||
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
@@ -164,6 +165,8 @@ namespace Barotrauma.Items.Components
|
||||
TextManager.Get("cave").Fallback(
|
||||
TextManager.Get("missiontype.nest"));
|
||||
|
||||
enemyLabel = TextManager.Get("enemysubmarine");
|
||||
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -216,8 +219,9 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 size = isConnectedToSteering ? controlBoxSize : new Vector2(0.46f, 0.4f);
|
||||
|
||||
controlContainer = new GUIFrame(new RectTransform(size, GuiFrame.RectTransform, Anchor.BottomLeft), "ItemUI");
|
||||
if (!isConnectedToSteering && !GUI.IsFourByThree())
|
||||
if (!isConnectedToSteering && GUI.AspectRatioDifference <= 0)
|
||||
{
|
||||
// In wider than 4:3 aspect ratio, we'll limit the max size.
|
||||
controlContainer.RectTransform.MaxSize = new Point((int)(380 * GUI.xScale), (int)(300 * GUI.yScale));
|
||||
}
|
||||
var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center)
|
||||
@@ -1019,6 +1023,38 @@ namespace Barotrauma.Items.Components
|
||||
cave.StartPos.ToVector2(), transducerCenter,
|
||||
DisplayScale, center, DisplayRadius);
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember is { } networkMember && GameMain.GameSession?.GameMode is PvPMode)
|
||||
{
|
||||
if (networkMember.ServerSettings.TrackOpponentInPvP
|
||||
&& Submarine.MainSubs[0] is { } coalitionSub
|
||||
&& Submarine.MainSubs[1] is { } separatistSub
|
||||
&& Character.Controlled is { } player)
|
||||
{
|
||||
Submarine whichSubToDraw = player.TeamID switch
|
||||
{
|
||||
CharacterTeamType.Team1 => separatistSub,
|
||||
CharacterTeamType.Team2 => coalitionSub,
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (whichSubToDraw != null)
|
||||
{
|
||||
DrawOffsetMarker(spriteBatch,
|
||||
enemyLabel.Value,
|
||||
Tags.Submarine,
|
||||
Tags.Enemy,
|
||||
whichSubToDraw.WorldPosition,
|
||||
transducerCenter,
|
||||
distanceThresholds: new Range<float>(start: MetersToUnits(150), end: MetersToUnits(1600)),
|
||||
offset: new Range<float>(start: MetersToUnits(100), end: MetersToUnits(400)),
|
||||
minOffset: MetersToUnits(10));
|
||||
|
||||
static float MetersToUnits(float m)
|
||||
=> m / Physics.DisplayToRealWorldRatio;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int missionIndex = 0;
|
||||
@@ -1042,7 +1078,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
if (HasMineralScanner && UseMineralScanner && CurrentMode == Mode.Active && MineralClusters != null &&
|
||||
(item.CurrentHull == null || !DetectSubmarineWalls))
|
||||
(item.CurrentHull == null || !DetectSubmarineWalls) &&
|
||||
HasPower)
|
||||
{
|
||||
foreach (var c in MineralClusters)
|
||||
{
|
||||
@@ -1076,7 +1113,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (!sub.ShowSonarMarker) { continue; }
|
||||
if (connectedSubs.Contains(sub)) { continue; }
|
||||
if (Level.Loaded != null && sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
if (sub.IsAboveLevel) { continue; }
|
||||
|
||||
if (item.Submarine != null || Character.Controlled != null)
|
||||
{
|
||||
@@ -1185,7 +1222,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (DockingPort dockingPort in DockingPort.List)
|
||||
{
|
||||
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
if (dockingPort.Item.Submarine.IsAboveLevel) { continue; }
|
||||
if (dockingPort.Item.IsHidden) { continue; }
|
||||
if (dockingPort.Item.Submarine == null) { continue; }
|
||||
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
||||
@@ -1198,8 +1235,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
//don't show the docking ports of the opposing team on the sonar
|
||||
if (item.Submarine != null &&
|
||||
item.Submarine != GameMain.NetworkMember?.RespawnManager?.RespawnShuttle &&
|
||||
dockingPort.Item.Submarine != GameMain.NetworkMember?.RespawnManager?.RespawnShuttle &&
|
||||
!item.Submarine.IsRespawnShuttle &&
|
||||
!dockingPort.Item.Submarine.IsRespawnShuttle &&
|
||||
!dockingPort.Item.Submarine.Info.IsOutpost &&
|
||||
!dockingPort.Item.Submarine.Info.IsBeacon)
|
||||
{
|
||||
@@ -1792,8 +1829,47 @@ namespace Barotrauma.Items.Components
|
||||
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f * blip.Alpha, sonarBlip.Origin, 0, scale, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used in DrawOffsetMarker to cache the randomized location of the marker
|
||||
/// </summary>
|
||||
private readonly Dictionary<Identifier, CachedLocation> cachedLocations = new Dictionary<Identifier, CachedLocation>();
|
||||
|
||||
private void DrawOffsetMarker(SpriteBatch spriteBatch, string label, Identifier iconIdentifier, Identifier targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, Range<float> distanceThresholds, Range<float> offset, float minOffset)
|
||||
{
|
||||
Vector2 pos;
|
||||
|
||||
if (!cachedLocations.TryGetValue(targetIdentifier, out CachedLocation cachedLocation))
|
||||
{
|
||||
cachedLocation = CreateCachedLocation();
|
||||
cachedLocations.Add(targetIdentifier, cachedLocation);
|
||||
pos = cachedLocation.Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Timing.TotalTime > cachedLocation.RecalculationTime)
|
||||
{
|
||||
cachedLocation = CreateCachedLocation();
|
||||
cachedLocations[targetIdentifier] = cachedLocation;
|
||||
}
|
||||
|
||||
pos = cachedLocation.Location;
|
||||
}
|
||||
|
||||
DrawMarker(spriteBatch, label, iconIdentifier, targetIdentifier, pos, transducerPosition, DisplayScale, center, DisplayRadius);
|
||||
|
||||
CachedLocation CreateCachedLocation()
|
||||
{
|
||||
float distance = Vector2.Distance(worldPosition, transducerPosition);
|
||||
|
||||
float maxOffset = MathHelper.Lerp(offset.Start, offset.End, MathHelper.Clamp((distance - distanceThresholds.Start) / (distanceThresholds.End - distanceThresholds.Start), 0.0f, 1.0f));
|
||||
|
||||
Vector2 randomPos = Rand.Vector(Rand.Range(minOffset, maxOffset));
|
||||
return new CachedLocation(worldPosition + randomPos, Timing.TotalTime + Rand.Range(10.0f, 30.0f));
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMarker(SpriteBatch spriteBatch, string label, Identifier iconIdentifier, object targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, float scale, Vector2 center, float radius,
|
||||
bool onlyShowTextOnMouseOver = false)
|
||||
bool onlyShowTextOnMouseOver = false)
|
||||
{
|
||||
float linearDist = Vector2.Distance(worldPosition, transducerPosition);
|
||||
float dist = linearDist;
|
||||
@@ -1903,25 +1979,6 @@ namespace Barotrauma.Items.Components
|
||||
2, GUIStyle.SmallFont);
|
||||
}
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
{
|
||||
base.RemoveComponentSpecific();
|
||||
sonarBlip?.Remove();
|
||||
pingCircle?.Remove();
|
||||
directionalPingCircle?.Remove();
|
||||
screenOverlay?.Remove();
|
||||
screenBackground?.Remove();
|
||||
lineSprite?.Remove();
|
||||
|
||||
foreach (var t in targetIcons.Values)
|
||||
{
|
||||
t.Item1.Remove();
|
||||
}
|
||||
targetIcons.Clear();
|
||||
|
||||
MineralClusters = null;
|
||||
}
|
||||
|
||||
public void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
msg.WriteBoolean(currentMode == Mode.Active);
|
||||
|
||||
@@ -57,24 +57,42 @@ namespace Barotrauma.Items.Components
|
||||
private GUIMessageBox enterOutpostPrompt, exitOutpostPrompt;
|
||||
|
||||
private bool levelStartSelected;
|
||||
[Serialize(defaultValue: false, isSaveable: IsPropertySaveable.Yes, AlwaysUseInstanceValues = true)]
|
||||
public bool LevelStartSelected
|
||||
{
|
||||
get { return levelStartTickBox.Selected; }
|
||||
set { levelStartTickBox.Selected = value; }
|
||||
get
|
||||
{
|
||||
return levelStartTickBox?.Selected ?? levelStartSelected;
|
||||
}
|
||||
set
|
||||
{
|
||||
TrySetTickBoxSelected(levelStartTickBox, ref levelStartSelected, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool levelEndSelected;
|
||||
[Serialize(defaultValue: false, isSaveable: IsPropertySaveable.Yes, AlwaysUseInstanceValues = true)]
|
||||
public bool LevelEndSelected
|
||||
{
|
||||
get { return levelEndTickBox.Selected; }
|
||||
set { levelEndTickBox.Selected = value; }
|
||||
get { return levelEndTickBox?.Selected ?? levelEndSelected; }
|
||||
set
|
||||
{
|
||||
TrySetTickBoxSelected(levelEndTickBox, ref levelEndSelected, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool maintainPos;
|
||||
[Serialize(defaultValue: false, isSaveable: IsPropertySaveable.Yes, AlwaysUseInstanceValues = true)]
|
||||
public bool MaintainPos
|
||||
{
|
||||
get { return maintainPosTickBox.Selected; }
|
||||
set { maintainPosTickBox.Selected = value; }
|
||||
get
|
||||
{
|
||||
return maintainPosTickBox?.Selected ?? maintainPos;
|
||||
}
|
||||
set
|
||||
{
|
||||
TrySetTickBoxSelected(maintainPosTickBox, ref maintainPos, value);
|
||||
}
|
||||
}
|
||||
|
||||
private float steerRadius;
|
||||
@@ -554,7 +572,7 @@ namespace Barotrauma.Items.Components
|
||||
int x = rect.X;
|
||||
int y = rect.Y;
|
||||
|
||||
if (Voltage < MinVoltage) { return; }
|
||||
if (!HasPower) { return; }
|
||||
|
||||
Rectangle velRect = new Rectangle(x + 20, y + 20, width - 40, height - 40);
|
||||
Vector2 steeringOrigin = steerArea.Rect.Center.ToVector2();
|
||||
@@ -759,7 +777,7 @@ namespace Barotrauma.Items.Components
|
||||
dockingButton.Text = dockText;
|
||||
}
|
||||
|
||||
if (Voltage < MinVoltage)
|
||||
if (!HasPower)
|
||||
{
|
||||
tipContainer.Visible = true;
|
||||
tipContainer.Text = noPowerTip;
|
||||
@@ -829,7 +847,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
if (!AutoPilot && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
steeringAdjustSpeed = character == null ? DefaultSteeringAdjustSpeed : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
||||
steeringAdjustSpeed = character == null ? DefaultSteeringAdjustSpeed : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel(Tags.HelmSkill) / 100.0f);
|
||||
Vector2 input = Vector2.Zero;
|
||||
if (PlayerInput.KeyDown(InputType.Left)) { input -= Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
|
||||
@@ -909,7 +927,7 @@ namespace Barotrauma.Items.Components
|
||||
if (targetPort.Docked || targetPort.Item.Submarine == null) { continue; }
|
||||
if (targetPort.Item.Submarine == controlledSub || targetPort.IsHorizontal != sourcePort.IsHorizontal) { continue; }
|
||||
if (targetPort.Item.Submarine.DockedTo?.Contains(sourcePort.Item.Submarine) ?? false) { continue; }
|
||||
if (Level.Loaded != null && targetPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
if (targetPort.Item.Submarine.IsAboveLevel) { continue; }
|
||||
if (sourceDir == targetPort.GetDir()) { continue; }
|
||||
|
||||
float dist = Vector2.DistanceSquared(sourcePort.Item.WorldPosition, targetPort.Item.WorldPosition);
|
||||
@@ -924,6 +942,21 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the specified tickbox, or if it hasn't been instantiated (yet?), just the value of the backing field.
|
||||
/// </summary>
|
||||
private void TrySetTickBoxSelected(GUITickBox tickBox, ref bool backingValue, bool newValue)
|
||||
{
|
||||
if (tickBox == null)
|
||||
{
|
||||
backingValue = newValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
tickBox.Selected = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
private bool NudgeButtonClicked(GUIButton btn, object userdata)
|
||||
{
|
||||
if (!MaintainPos || !AutoPilot)
|
||||
|
||||
Reference in New Issue
Block a user