Unstable v0.1300.0.0 (February 19th 2021)

This commit is contained in:
Joonas Rikkonen
2021-02-25 13:44:23 +02:00
parent b772654326
commit 24cbef485a
441 changed files with 21343 additions and 8562 deletions
@@ -7,6 +7,7 @@ using System.Xml.Linq;
using System.Linq;
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
using Voronoi2;
namespace Barotrauma
{
@@ -21,6 +22,7 @@ namespace Barotrauma
public readonly float OutCondition;
//should the condition of the deconstructed item be copied to the output items
public readonly bool CopyCondition;
public float Commonness { get; }
public DeconstructItem(XElement element)
{
@@ -29,6 +31,7 @@ namespace Barotrauma
MaxCondition = element.GetAttributeFloat("maxcondition", 1.0f);
OutCondition = element.GetAttributeFloat("outcondition", 1.0f);
CopyCondition = element.GetAttributeBool("copycondition", false);
Commonness = element.GetAttributeFloat("commonness", 1.0f);
}
}
@@ -65,6 +68,7 @@ namespace Barotrauma
public readonly float RequiredTime;
public readonly float OutCondition; //Percentage-based from 0 to 1
public readonly List<Skill> RequiredSkills;
public int Amount { get; }
public FabricationRecipe(XElement element, ItemPrefab itemPrefab)
{
@@ -78,6 +82,7 @@ namespace Barotrauma
RequiredTime = element.GetAttributeFloat("requiredtime", 1.0f);
OutCondition = element.GetAttributeFloat("outcondition", 1.0f);
RequiredItems = new List<RequiredItem>();
Amount = element.GetAttributeInt("amount", 1);
foreach (XElement subElement in element.Elements())
{
@@ -117,7 +122,7 @@ namespace Barotrauma
continue;
}
var existing = RequiredItems.Find(r => r.ItemPrefabs.Count == 1 && r.ItemPrefabs[0] == requiredItem);
var existing = RequiredItems.Find(r => r.ItemPrefabs.Count == 1 && r.ItemPrefabs[0] == requiredItem && MathUtils.NearlyEqual(r.MinCondition, minCondition));
if (existing == null)
{
RequiredItems.Add(new RequiredItem(requiredItem, count, minCondition, useCondition));
@@ -136,7 +141,7 @@ namespace Barotrauma
continue;
}
var existing = RequiredItems.Find(r => r.ItemPrefabs.SequenceEqual(matchingItems));
var existing = RequiredItems.Find(r => r.ItemPrefabs.SequenceEqual(matchingItems) && MathUtils.NearlyEqual(r.MinCondition, minCondition));
if (existing == null)
{
RequiredItems.Add(new RequiredItem(matchingItems, count, minCondition, useCondition));
@@ -156,7 +161,10 @@ namespace Barotrauma
{
public readonly HashSet<string> Primary = new HashSet<string>();
public readonly HashSet<string> Secondary = new HashSet<string>();
public float SpawnProbability { get; private set; }
public float MaxCondition { get; private set; }
public float MinCondition { get; private set; }
public int MinAmount { get; private set; }
public int MaxAmount { get; private set; }
@@ -167,6 +175,8 @@ namespace Barotrauma
SpawnProbability = element.GetAttributeFloat("spawnprobability", 0.0f);
MinAmount = element.GetAttributeInt("minamount", 0);
MaxAmount = Math.Max(MinAmount, element.GetAttributeInt("maxamount", 0));
MaxCondition = element.GetAttributeFloat("maxcondition", 100f);
MinCondition = element.GetAttributeFloat("mincondition", 0f);
if (element.Attribute("spawnprobability") == null)
{
@@ -185,7 +195,7 @@ namespace Barotrauma
}
}
partial class ItemPrefab : MapEntityPrefab
partial class ItemPrefab : MapEntityPrefab, IHasUintIdentifier
{
private readonly string name;
public override string Name => name;
@@ -205,7 +215,7 @@ namespace Barotrauma
protected Vector2 size;
private float impactTolerance;
private readonly PriceInfo defaultPrice;
public readonly PriceInfo DefaultPrice;
private readonly Dictionary<string, PriceInfo> locationPrices;
/// <summary>
@@ -465,6 +475,24 @@ namespace Barotrauma
private set;
} = new Dictionary<string, float>();
public Dictionary<string, FixedQuantityResourceInfo> LevelQuantity
{
get;
} = new Dictionary<string, FixedQuantityResourceInfo>();
public struct FixedQuantityResourceInfo
{
public int ClusterQuantity { get; }
public int ClusterSize { get; }
public bool IsIslandSpecifc { get; }
public FixedQuantityResourceInfo(int clusterQuantity, int clusterSize, bool isIslandSpecific)
{
ClusterQuantity = clusterQuantity;
ClusterSize = clusterSize;
IsIslandSpecifc = isIslandSpecific;
}
}
[Serialize(true, false)]
public bool CanFlipX { get; private set; }
@@ -479,9 +507,28 @@ namespace Barotrauma
public bool CanSpriteFlipY { get; private set; }
private int maxStackSize;
[Serialize(1, false)]
public int MaxStackSize
{
get { return maxStackSize; }
set { maxStackSize = MathHelper.Clamp(value, 1, Inventory.MaxStackSize); }
}
public Vector2 Size => size;
public bool CanBeBought => (defaultPrice != null && defaultPrice.CanBeBought) || (locationPrices != null && locationPrices.Any(p => p.Value.CanBeBought));
public bool CanBeBought => (DefaultPrice != null && DefaultPrice.CanBeBought) || (locationPrices != null && locationPrices.Any(p => p.Value.CanBeBought));
/// <summary>
/// Any item with a Price element in the definition can be sold everywhere.
/// </summary>
public bool CanBeSold => DefaultPrice != null;
public bool RandomDeconstructionOutput { get; }
public int RandomDeconstructionOutputAmount { get; }
public uint UIntIdentifier { get; set; }
public static void RemoveByFile(string filePath) => Prefabs.RemoveByFile(filePath);
@@ -597,11 +644,13 @@ namespace Barotrauma
originalName = element.GetAttributeString("name", "");
name = originalName;
identifier = element.GetAttributeString("identifier", "");
if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category))
string categoryStr = element.GetAttributeString("category", "Misc");
if (!Enum.TryParse(categoryStr, true, out MapEntityCategory category))
{
category = MapEntityCategory.Misc;
}
Category = category;
Category = category;
var parentType = element.Parent?.GetAttributeString("itemtype", "") ?? string.Empty;
@@ -725,7 +774,7 @@ namespace Barotrauma
if (locationPrices == null) { locationPrices = new Dictionary<string, PriceInfo>(); }
if (subElement.Attribute("baseprice") != null)
{
foreach (Tuple<string, PriceInfo> priceInfo in PriceInfo.CreatePriceInfos(subElement, out defaultPrice))
foreach (Tuple<string, PriceInfo> priceInfo in PriceInfo.CreatePriceInfos(subElement, out DefaultPrice))
{
if (priceInfo == null) { continue; }
locationPrices.Add(priceInfo.Item1, priceInfo.Item2);
@@ -857,6 +906,8 @@ namespace Barotrauma
case "deconstruct":
DeconstructTime = subElement.GetAttributeFloat("time", 1.0f);
AllowDeconstruct = true;
RandomDeconstructionOutput = subElement.GetAttributeBool("chooserandom", false);
RandomDeconstructionOutputAmount = subElement.GetAttributeInt("amount", 1);
foreach (XElement deconstructItem in subElement.Elements())
{
if (deconstructItem.Attribute("name") != null)
@@ -864,10 +915,9 @@ namespace Barotrauma
DebugConsole.ThrowError("Error in item config \"" + Name + "\" - use item identifiers instead of names to configure the deconstruct items.");
continue;
}
DeconstructItems.Add(new DeconstructItem(deconstructItem));
}
RandomDeconstructionOutputAmount = Math.Min(RandomDeconstructionOutputAmount, DeconstructItems.Count);
break;
case "fabricate":
case "fabricable":
@@ -898,12 +948,25 @@ namespace Barotrauma
break;
case "levelresource":
foreach (XElement levelCommonnessElement in subElement.Elements())
foreach (XElement levelCommonnessElement in subElement.GetChildElements("commonness"))
{
string levelName = levelCommonnessElement.GetAttributeString("leveltype", "").ToLowerInvariant();
if (!LevelCommonness.ContainsKey(levelName))
if (!levelCommonnessElement.GetAttributeBool("fixedquantity", false))
{
LevelCommonness.Add(levelName, levelCommonnessElement.GetAttributeFloat("commonness", 0.0f));
if (!LevelCommonness.ContainsKey(levelName))
{
LevelCommonness.Add(levelName, levelCommonnessElement.GetAttributeFloat("commonness", 0.0f));
}
}
else
{
if (!LevelQuantity.ContainsKey(levelName))
{
LevelQuantity.Add(levelName, new FixedQuantityResourceInfo(
levelCommonnessElement.GetAttributeInt("clusterquantity", 0),
levelCommonnessElement.GetAttributeInt("clustersize", 0),
levelCommonnessElement.GetAttributeBool("isislandspecific", false)));
}
}
}
break;
@@ -926,7 +989,14 @@ namespace Barotrauma
// with separate Price elements and there is no default price explicitly set
if (locationPrices != null && locationPrices.Any())
{
defaultPrice ??= new PriceInfo(GetMinPrice() ?? 0, false);
DefaultPrice ??= new PriceInfo(GetMinPrice() ?? 0, false);
}
//backwards compatibility
if (categoryStr.Equals("Thalamus", StringComparison.OrdinalIgnoreCase))
{
Category = MapEntityCategory.Wrecked;
Subcategory = "Thalamus";
}
if (sprite == null)
@@ -964,6 +1034,7 @@ namespace Barotrauma
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
Prefabs.Add(this, allowOverriding);
this.CalculatePrefabUIntIdentifier(Prefabs);
}
public float GetTreatmentSuitability(string treatmentIdentifier)
@@ -981,7 +1052,7 @@ namespace Barotrauma
}
else
{
return defaultPrice;
return DefaultPrice;
}
}
@@ -1026,9 +1097,9 @@ namespace Barotrauma
int? minPrice = locationPrices != null && locationPrices.Values.Any() ? locationPrices?.Values.Min(p => p.Price) : null;
if (minPrice.HasValue)
{
if (defaultPrice != null)
if (DefaultPrice != null)
{
return minPrice < defaultPrice.Price ? minPrice : defaultPrice.Price;
return minPrice < DefaultPrice.Price ? minPrice : DefaultPrice.Price;
}
else
{
@@ -1037,36 +1108,38 @@ namespace Barotrauma
}
else
{
return defaultPrice?.Price;
return DefaultPrice?.Price;
}
}
public bool IsContainerPreferred(ItemContainer itemContainer, out bool isPreferencesDefined, out bool isSecondary)
public bool IsContainerPreferred(Item item, ItemContainer targetContainer, out bool isPreferencesDefined, out bool isSecondary)
{
isPreferencesDefined = PreferredContainers.Any();
isSecondary = false;
if (!isPreferencesDefined) { return true; }
if (PreferredContainers.Any(pc => IsContainerPreferred(pc.Primary, itemContainer)))
if (PreferredContainers.Any(pc => IsItemConditionAcceptable(item, pc) && IsContainerPreferred(pc.Primary, targetContainer)))
{
return true;
}
isSecondary = true;
return PreferredContainers.Any(pc => IsContainerPreferred(pc.Secondary, itemContainer));
return PreferredContainers.Any(pc => IsItemConditionAcceptable(item, pc) && IsContainerPreferred(pc.Secondary, targetContainer));
}
public bool IsContainerPreferred(string[] identifiersOrTags, out bool isPreferencesDefined, out bool isSecondary)
public bool IsContainerPreferred(Item item, string[] identifiersOrTags, out bool isPreferencesDefined, out bool isSecondary)
{
isPreferencesDefined = PreferredContainers.Any();
isSecondary = false;
if (!isPreferencesDefined) { return true; }
if (PreferredContainers.Any(pc => IsContainerPreferred(pc.Primary, identifiersOrTags)))
if (PreferredContainers.Any(pc => IsItemConditionAcceptable(item, pc) && IsContainerPreferred(pc.Primary, identifiersOrTags)))
{
return true;
}
isSecondary = true;
return PreferredContainers.Any(pc => IsContainerPreferred(pc.Secondary, identifiersOrTags));
return PreferredContainers.Any(pc => IsItemConditionAcceptable(item, pc) && IsContainerPreferred(pc.Secondary, identifiersOrTags));
}
private bool IsItemConditionAcceptable(Item item, PreferredContainer pc) => item.ConditionPercentage >= pc.MinCondition && item.ConditionPercentage <= pc.MaxCondition;
public static bool IsContainerPreferred(IEnumerable<string> preferences, ItemContainer c) => preferences.Any(id => c.Item.Prefab.Identifier == id || c.Item.HasTag(id));
public static bool IsContainerPreferred(IEnumerable<string> preferences, IEnumerable<string> ids) => ids.Any(id => preferences.Contains(id));
}