Unstable v0.19.3.0

This commit is contained in:
Juan Pablo Arce
2022-09-02 15:10:56 -03:00
parent 28789616bd
commit 3f2c843247
336 changed files with 7152 additions and 7739 deletions
@@ -1,6 +1,4 @@
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class AbilityConditionAboveVitality : AbilityConditionDataless
{
@@ -13,7 +11,7 @@ namespace Barotrauma.Abilities
protected override bool MatchesConditionSpecific()
{
return character.HealthPercentage / 100f > vitalityPercentage;
return character.Vitality / character.MaxVitality > vitalityPercentage;
}
}
}
@@ -1,11 +1,10 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
{
class AbilityConditionAlliesAboveVitality : AbilityConditionDataless
{
float vitalityPercentage;
readonly float vitalityPercentage;
public AbilityConditionAlliesAboveVitality(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
{
@@ -1,7 +1,4 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class AbilityConditionCoauthor : AbilityConditionDataless
{
@@ -1,7 +1,4 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class AbilityConditionCrouched : AbilityConditionDataless
{
@@ -1,28 +1,22 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class AbilityConditionHasAffliction : AbilityConditionDataless
{
private string afflictionIdentifier;
private float minimumPercentage;
private readonly Identifier afflictionIdentifier;
private readonly float minimumPercentage;
public AbilityConditionHasAffliction(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
{
afflictionIdentifier = conditionElement.GetAttributeString("afflictionidentifier", "");
afflictionIdentifier = conditionElement.GetAttributeIdentifier("afflictionidentifier", Identifier.Empty);
minimumPercentage = conditionElement.GetAttributeFloat("minimumpercentage", 0f);
}
protected override bool MatchesConditionSpecific()
{
if (!string.IsNullOrEmpty(afflictionIdentifier))
if (!afflictionIdentifier.IsEmpty)
{
var affliction = character.CharacterHealth.GetAffliction(afflictionIdentifier);
if (affliction == null) { return false; }
return minimumPercentage <= affliction.Strength / affliction.Prefab.MaxStrength;
}
return false;
@@ -3,55 +3,43 @@ using Barotrauma.Items.Components;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma.Abilities
{
class AbilityConditionHasItem : AbilityConditionDataless
{
// not used for anything atm, will be used for clown subclass
private readonly string[] tags;
private InvSlotType? invSlotType;
bool requireAll;
private List<Item> items = new List<Item>();
readonly bool requireAll;
public AbilityConditionHasItem(CharacterTalent characterTalent, ContentXElement conditionElement) : base(characterTalent, conditionElement)
{
tags = conditionElement.GetAttributeStringArray("tags", Array.Empty<string>(), convertToLowerInvariant: true);
tags = conditionElement.GetAttributeStringArray("tags", Array.Empty<string>());
requireAll = conditionElement.GetAttributeBool("requireall", false);
//this.invSlotType = invSlotType;
}
protected override bool MatchesConditionSpecific()
{
items.Clear();
if (tags.Any())
if (tags.None())
{
foreach (string tag in tags)
{
// there is a better method, should use that instead
if (character.GetEquippedItem(tag, invSlotType) is Item foundItem)
{
items.Add(foundItem);
}
}
}
else
{
if (character.GetEquippedItem(null, invSlotType) is Item foundItem)
{
items.Add(foundItem);
}
return character.GetEquippedItem(null) is Item;
}
if (requireAll)
{
return (items.Count >= tags.Count());
foreach (string tag in tags)
{
if (character.GetEquippedItem(tag) == null) { return false; }
}
return true;
}
else
{
return items.Any();
foreach (string tag in tags)
{
if (character.GetEquippedItem(tag) != null) { return true; }
}
return false;
}
}
}
@@ -1,7 +1,4 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class AbilityConditionHasVelocity : AbilityConditionDataless
{
@@ -1,7 +1,4 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class AbilityConditionShipFlooded : AbilityConditionDataless
{
@@ -14,8 +11,14 @@ namespace Barotrauma.Abilities
protected override bool MatchesConditionSpecific()
{
if (!character.IsInFriendlySub) { return false; }
float currentFloodPercentage = character.Submarine.GetHulls(false).Average(h => h.WaterPercentage);
return currentFloodPercentage / 100 > floodPercentage;
float waterVolume = 0.0f, totalVolume = 0.0f;
foreach (Hull hull in Hull.HullList)
{
if (hull.Submarine != character.Submarine) { continue; }
waterVolume += hull.WaterVolume;
totalVolume += hull.Volume;
}
return (waterVolume / totalVolume) > floodPercentage;
}
}
}
@@ -1,7 +1,4 @@
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class CharacterAbilityModifyStatToFlooding : CharacterAbility
{
@@ -22,8 +19,14 @@ namespace Barotrauma.Abilities
if (conditionsMatched && Character.IsInFriendlySub)
{
float currentFloodPercentage = Character.Submarine.GetHulls(false).Average(h => h.WaterPercentage);
lastValue = currentFloodPercentage / 100f * maxValue;
float waterVolume = 0.0f, totalVolume = 0.0f;
foreach (Hull hull in Hull.HullList)
{
if (hull.Submarine != Character.Submarine) { continue; }
waterVolume += hull.WaterVolume;
totalVolume += hull.Volume;
}
lastValue = (totalVolume == 0.0f ? 1.0f : waterVolume / totalVolume) * maxValue;
Character.ChangeStat(statType, lastValue);
}
else
@@ -1,8 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class CharacterAbilityUnlockTree : CharacterAbility
{
@@ -14,22 +10,19 @@ namespace Barotrauma.Abilities
{
if (!TalentTree.JobTalentTrees.TryGet(Character.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
var subTree = talentTree.TalentSubTrees.Find(t => t.TalentOptionStages.Any(ts => ts.Talents.Contains(CharacterTalent.Prefab)));
var subTree = talentTree.TalentSubTrees.Find(t => t.AllTalentIdentifiers.Contains(CharacterTalent.Prefab.Identifier));
if (subTree == null) { return; }
subTree.ForceUnlock = true;
if (!addingFirstTime) { return; }
foreach (var talentOption in subTree.TalentOptionStages)
foreach (var talentId in subTree.AllTalentIdentifiers)
{
foreach (var talent in talentOption.Talents)
if (talentId == CharacterTalent.Prefab.Identifier) { continue; }
if (Character.GiveTalent(talentId))
{
if (talent == CharacterTalent.Prefab) { continue; }
if (Character.GiveTalent(talent))
{
Character.Info.AdditionalTalentPoints++;
}
}
Character.Info.AdditionalTalentPoints++;
}
}
}
}
@@ -1,10 +1,4 @@
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Abilities
namespace Barotrauma.Abilities
{
class CharacterAbilityInsurancePolicy : CharacterAbility
{
@@ -19,10 +13,10 @@ namespace Barotrauma.Abilities
protected override void ApplyEffect(AbilityObject abilityObject)
{
if (Character?.Info is CharacterInfo info)
if (Character?.Info is CharacterInfo info && GameMain.GameSession?.GameMode is CampaignMode campaign)
{
int totalAmount = moneyPerMission * info.MissionsCompletedSinceDeath;
Character.GiveMoney(totalAmount);
campaign.Bank.Give(totalAmount);
GameAnalyticsManager.AddMoneyGainedEvent(totalAmount, GameAnalyticsManager.MoneySource.Ability, CharacterTalent.Prefab.Identifier.Value);
}
}
@@ -15,7 +15,7 @@ namespace Barotrauma.Abilities
public readonly AbilityEffectType AbilityEffectType;
protected int maxTriggerCount { get; }
protected readonly int maxTriggerCount;
protected int timesTriggered = 0;
@@ -88,8 +88,6 @@ namespace Barotrauma.Abilities
// XML
private AbilityCondition ConstructCondition(CharacterTalent characterTalent, ContentXElement conditionElement, bool errorMessages = true)
{
AbilityCondition newCondition = null;
Type conditionType;
string type = conditionElement.Name.ToString().ToLowerInvariant();
try
@@ -109,6 +107,7 @@ namespace Barotrauma.Abilities
object[] args = { characterTalent, conditionElement };
AbilityCondition newCondition;
try
{
newCondition = (AbilityCondition)Activator.CreateInstance(conditionType, args);
@@ -210,8 +209,7 @@ namespace Barotrauma.Abilities
public static AbilityFlags ParseFlagType(string flagTypeString, string debugIdentifier)
{
AbilityFlags flagType = AbilityFlags.None;
if (!Enum.TryParse(flagTypeString, true, out flagType))
if (!Enum.TryParse(flagTypeString, true, out AbilityFlags flagType))
{
DebugConsole.ThrowError("Invalid flag type type \"" + flagTypeString + "\" in CharacterTalent (" + debugIdentifier + ")");
}
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -19,7 +18,12 @@ namespace Barotrauma
public static readonly PrefabCollection<TalentTree> JobTalentTrees = new PrefabCollection<TalentTree>();
public readonly List<TalentSubTree> TalentSubTrees = new List<TalentSubTree>();
public readonly ImmutableArray<TalentSubTree> TalentSubTrees;
/// <summary>
/// Talent identifiers of all the talents in this tree
/// </summary>
public readonly ImmutableHashSet<Identifier> AllTalentIdentifiers;
public ContentXElement ConfigElement
{
@@ -36,16 +40,19 @@ namespace Barotrauma
DebugConsole.ThrowError($"No job defined for talent tree in \"{file.Path}\"!");
return;
}
List<TalentSubTree> subTrees = new List<TalentSubTree>();
foreach (var subTreeElement in element.GetChildElements("subtree"))
{
TalentSubTrees.Add(new TalentSubTree(subTreeElement));
subTrees.Add(new TalentSubTree(subTreeElement));
}
TalentSubTrees = subTrees.ToImmutableArray();
AllTalentIdentifiers = TalentSubTrees.SelectMany(t => t.AllTalentIdentifiers).ToImmutableHashSet();
}
public bool TalentIsInTree(Identifier talentIdentifier)
{
return TalentSubTrees.SelectMany(s => s.TalentOptionStages.SelectMany(o => o.Talents.Select(t => t.Identifier))).Any(c => c == talentIdentifier);
return AllTalentIdentifiers.Contains(talentIdentifier);
}
public static bool IsViableTalentForCharacter(Character character, Identifier talentIdentifier)
@@ -54,6 +61,7 @@ namespace Barotrauma
}
// i hate this function - markus
// me too - joonas
public static TalentTreeStageState GetTalentOptionStageState(Character character, Identifier subTreeIdentifier, int index, List<Identifier> selectedTalents)
{
if (character?.Info?.Job.Prefab is null) { return TalentTreeStageState.Invalid; }
@@ -66,12 +74,12 @@ namespace Barotrauma
TalentOption targetTalentOption = subTree.TalentOptionStages[index];
if (targetTalentOption.Talents.Any(t => character.HasTalent(t.Identifier)))
if (targetTalentOption.TalentIdentifiers.Any(t => character.HasTalent(t)))
{
return TalentTreeStageState.Unlocked;
}
if (targetTalentOption.Talents.Any(t => selectedTalents.Contains(t.Identifier)))
if (targetTalentOption.TalentIdentifiers.Any(t => selectedTalents.Contains(t)))
{
return TalentTreeStageState.Highlighted;
}
@@ -83,8 +91,8 @@ namespace Barotrauma
if (lastindex >= 0)
{
TalentOption lastLatentOption = subTree.TalentOptionStages[lastindex];
hasTalentInLastTier = lastLatentOption.Talents.Any(HasTalent);
isLastTalentPurchased = lastLatentOption.Talents.Any(t => character.HasTalent(t.Identifier));
hasTalentInLastTier = lastLatentOption.TalentIdentifiers.Any(HasTalent);
isLastTalentPurchased = lastLatentOption.TalentIdentifiers.Any(t => character.HasTalent(t));
}
if (!hasTalentInLastTier)
@@ -101,9 +109,9 @@ namespace Barotrauma
return TalentTreeStageState.Locked;
bool HasTalent(TalentPrefab t)
bool HasTalent(Identifier talentId)
{
return selectedTalents.Contains(t.Identifier);
return selectedTalents.Contains(talentId);
}
}
@@ -117,14 +125,14 @@ namespace Barotrauma
foreach (var subTree in talentTree.TalentSubTrees)
{
if (subTree.ForceUnlock && subTree.TalentOptionStages.Any(option => option.Talents.Any(t => t.Identifier == talentIdentifier))) { return true; }
if (subTree.ForceUnlock && subTree.TalentOptionStages.Any(option => option.TalentIdentifiers.Contains(talentIdentifier))) { return true; }
foreach (var talentOptionStage in subTree.TalentOptionStages)
{
bool hasTalentInThisTier = talentOptionStage.Talents.Any(t => selectedTalents.Contains(t.Identifier));
bool hasTalentInThisTier = talentOptionStage.TalentIdentifiers.Any(t => selectedTalents.Contains(t));
if (!hasTalentInThisTier)
{
if (talentOptionStage.Talents.Any(t => t.Identifier == talentIdentifier))
if (talentOptionStage.TalentIdentifiers.Contains(talentIdentifier))
{
return true;
}
@@ -170,18 +178,21 @@ namespace Barotrauma
public bool ForceUnlock;
public readonly List<TalentOption> TalentOptionStages = new List<TalentOption>();
public readonly ImmutableArray<TalentOption> TalentOptionStages;
public readonly ImmutableHashSet<Identifier> AllTalentIdentifiers;
public TalentSubTree(ContentXElement subTreeElement)
{
Identifier = subTreeElement.GetAttributeIdentifier("identifier", "");
DisplayName = TextManager.Get("talenttree." + Identifier).Fallback(Identifier.Value);
List<TalentOption> talentOptionStages = new List<TalentOption>();
foreach (var talentOptionsElement in subTreeElement.GetChildElements("talentoptions"))
{
TalentOptionStages.Add(new TalentOption(talentOptionsElement, Identifier));
talentOptionStages.Add(new TalentOption(talentOptionsElement, Identifier));
}
TalentOptionStages = talentOptionStages.ToImmutableArray();
AllTalentIdentifiers = TalentOptionStages.SelectMany(t => t.TalentIdentifiers).ToImmutableHashSet();
}
}
@@ -190,8 +201,12 @@ namespace Barotrauma
{
private readonly ImmutableHashSet<Identifier> talentIdentifiers;
public IEnumerable<TalentPrefab> Talents
=> talentIdentifiers.Select(id => TalentPrefab.TalentPrefabs[id]);
public IEnumerable<Identifier> TalentIdentifiers => talentIdentifiers;
public bool HasTalent(Identifier talentIdentifier)
{
return talentIdentifiers.Contains(talentIdentifier);
}
public TalentOption(ContentXElement talentOptionsElement, Identifier debugIdentifier)
{