Faction Test 100.13.0.0

This commit is contained in:
Markus Isberg
2023-01-11 15:36:23 +02:00
parent 1650735468
commit caa5a2f762
145 changed files with 2100 additions and 1111 deletions
@@ -57,13 +57,12 @@ namespace Barotrauma
if (characterList.Any())
{
if (location?.Reputation is { } reputation && Faction.GetPlayerAffiliationStatus(reputation.Identifier, characterList) is FactionAffiliation.Positive)
if (location?.Faction is { } faction && Faction.GetPlayerAffiliationStatus(faction, characterList) is FactionAffiliation.Positive)
{
price *= 1f - characterList.Max(static c => c.GetStatValue(StatTypes.ShipyardBuyMultiplierAffiliated));
}
price *= 1f - characterList.Max(static c => c.GetStatValue(StatTypes.ShipyardBuyMultiplier));
}
return (int)price;
}
}
@@ -270,10 +269,59 @@ namespace Barotrauma
}
}
internal partial class UpgradePrefab : UpgradeContentPrefab
internal readonly struct UpgradeResourceCost
{
public readonly int Amount;
private readonly ImmutableArray<Identifier> targetTags;
public readonly Range<int> TargetLevels;
public UpgradeResourceCost(ContentXElement element)
{
Amount = element.GetAttributeInt("amount", 0);
targetTags = element.GetAttributeIdentifierArray("item", Array.Empty<Identifier>())!.ToImmutableArray();
TargetLevels = element.GetAttributeRange("levels", new Range<int>(0, 99));
}
public bool AppliesForLevel(int currentLevel) => TargetLevels.Contains(currentLevel);
public bool AppliesForLevel(Range<int> newLevels) => newLevels.Start <= TargetLevels.End && newLevels.End >= TargetLevels.Start;
public bool MatchesItem(Item item) => MatchesItem(item.Prefab);
public bool MatchesItem(ItemPrefab item)
{
foreach (Identifier tag in targetTags)
{
if (tag.Equals(item.Identifier) || item.Tags.Contains(tag)) { return true; }
}
return false;
}
}
internal readonly struct ApplicableResourceCollection
{
public readonly ImmutableArray<ItemPrefab> MatchingItems;
public readonly UpgradeResourceCost Cost;
public readonly int Count;
public ApplicableResourceCollection(IEnumerable<ItemPrefab> matchingItems, int count, UpgradeResourceCost cost)
{
MatchingItems = matchingItems.ToImmutableArray();
Count = count;
Cost = cost;
}
public static ApplicableResourceCollection CreateFor(UpgradeResourceCost cost)
{
return new ApplicableResourceCollection(ItemPrefab.Prefabs.Where(cost.MatchesItem), cost.Amount, cost);
}
}
internal sealed partial class UpgradePrefab : UpgradeContentPrefab
{
public static readonly PrefabCollection<UpgradePrefab> Prefabs = new PrefabCollection<UpgradePrefab>(
onAdd: (prefab, isOverride) =>
onAdd: static (prefab, isOverride) =>
{
if (!prefab.SuppressWarnings && !isOverride)
{
@@ -342,6 +390,7 @@ namespace Barotrauma
private Dictionary<string, string[]> targetProperties { get; }
private readonly ImmutableArray<UpgradeMaxLevelMod> MaxLevelsMods;
public readonly ImmutableHashSet<UpgradeResourceCost> ResourceCosts;
public UpgradePrefab(ContentXElement element, UpgradeModulesFile file) : base(element, file)
{
@@ -354,6 +403,7 @@ namespace Barotrauma
var targetProperties = new Dictionary<string, string[]>();
var maxLevels = new List<UpgradeMaxLevelMod>();
var resourceCosts = new HashSet<UpgradeResourceCost>();
Identifier nameIdentifier = element.GetAttributeIdentifier("nameidentifier", "");
if (!nameIdentifier.IsEmpty)
@@ -396,6 +446,11 @@ namespace Barotrauma
maxLevels.Add(new UpgradeMaxLevelMod(subElement));
break;
}
case "resourcecost":
{
resourceCosts.Add(new UpgradeResourceCost(subElement));
break;
}
#if CLIENT
case "decorativesprite":
{
@@ -427,6 +482,7 @@ namespace Barotrauma
this.targetProperties = targetProperties;
MaxLevelsMods = maxLevels.ToImmutableArray();
ResourceCosts = resourceCosts.ToImmutableHashSet();
upgradeCategoryIdentifiers = element.GetAttributeIdentifierArray("categories", Array.Empty<Identifier>())?
.ToImmutableHashSet() ?? ImmutableHashSet<Identifier>.Empty;
@@ -469,6 +525,58 @@ namespace Barotrauma
return GetMaxLevel(info) > 0;
}
public bool HasResourcesToUpgrade(Character? character, int currentLevel)
{
if (character is null) { return false; }
if (!ResourceCosts.Any()) { return true; }
List<Item> allItems = character.Inventory.FindAllItems(recursive: true);
return ResourceCosts.Where(cost => cost.AppliesForLevel(currentLevel)).All(cost => cost.Amount <= allItems.Count(cost.MatchesItem));
}
public bool TryTakeResources(Character character, int currentLevel)
{
IEnumerable<UpgradeResourceCost> costs = ResourceCosts.Where(cost => cost.AppliesForLevel(currentLevel));
if (!costs.Any()) { return true; }
List<Item> allItems = character.Inventory.FindAllItems(recursive: true);
HashSet<Item> itemsToRemove = new HashSet<Item>();
foreach (UpgradeResourceCost cost in costs)
{
int amountNeeded = cost.Amount;
foreach (Item item in allItems.Where(cost.MatchesItem))
{
itemsToRemove.Add(item);
amountNeeded--;
if (amountNeeded <= 0) { break; }
}
if (amountNeeded > 0) { return false; }
}
foreach (Item item in itemsToRemove)
{
item.Remove();
}
if (GameMain.IsMultiplayer) { character.Inventory.CreateNetworkEvent(); }
return true;
}
public ImmutableArray<ApplicableResourceCollection> GetApplicableResources(int level)
{
var applicableCosts = ResourceCosts.Where(cost => cost.AppliesForLevel(level)).ToImmutableHashSet();
var costs = applicableCosts.Any()
? applicableCosts.Select(ApplicableResourceCollection.CreateFor).ToImmutableArray()
: ImmutableArray<ApplicableResourceCollection>.Empty;
return costs;
}
public bool IsDisallowed(MapEntity item)
{
return item.DisallowedUpgradeSet.Contains(Identifier)