v1.0.13.1 (first post-1.0 patch)
This commit is contained in:
+3
-1
@@ -6,11 +6,13 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
private readonly ItemTalentStats stat;
|
||||
private readonly float value;
|
||||
private readonly bool stackable;
|
||||
|
||||
public CharacterAbilityGiveItemStat(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
stat = abilityElement.GetAttributeEnum("stattype", ItemTalentStats.None);
|
||||
value = abilityElement.GetAttributeFloat("value", 0f);
|
||||
stackable = abilityElement.GetAttributeBool("stackable", true);
|
||||
}
|
||||
|
||||
protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate)
|
||||
@@ -25,7 +27,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
if (abilityObject is not IAbilityItem ability) { return; }
|
||||
|
||||
ability.Item.StatManager.ApplyStat(stat, value, CharacterTalent);
|
||||
ability.Item.StatManager.ApplyStat(stat, stackable, value, CharacterTalent);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -9,12 +9,14 @@ namespace Barotrauma.Abilities
|
||||
private readonly ItemTalentStats stat;
|
||||
private readonly float value;
|
||||
private readonly ImmutableHashSet<Identifier> tags;
|
||||
private readonly bool stackable;
|
||||
|
||||
public CharacterAbilityGiveItemStatToTags(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
|
||||
{
|
||||
stat = abilityElement.GetAttributeEnum("stattype", ItemTalentStats.None);
|
||||
value = abilityElement.GetAttributeFloat("value", 0f);
|
||||
tags = abilityElement.GetAttributeIdentifierImmutableHashSet("tags", ImmutableHashSet<Identifier>.Empty);
|
||||
stackable = abilityElement.GetAttributeBool("stackable", true);
|
||||
}
|
||||
|
||||
public override void InitializeAbility(bool addingFirstTime)
|
||||
@@ -41,7 +43,7 @@ namespace Barotrauma.Abilities
|
||||
{
|
||||
if (item.HasTag(tags) || tags.Contains(item.Prefab.Identifier))
|
||||
{
|
||||
item.StatManager.ApplyStat(stat, value, CharacterTalent);
|
||||
item.StatManager.ApplyStat(stat, stackable, value, CharacterTalent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -217,6 +217,11 @@ namespace Barotrauma.Abilities
|
||||
|
||||
public static StatTypes ParseStatType(string statTypeString, string debugIdentifier)
|
||||
{
|
||||
//backwards compatibility
|
||||
if (statTypeString.Equals("MedicalItemDurationMultiplier", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
statTypeString = "BuffItemApplyingMultiplier";
|
||||
}
|
||||
if (!Enum.TryParse(statTypeString, true, out StatTypes statType))
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid stat type type \"" + statTypeString + "\" in CharacterTalent (" + debugIdentifier + ")");
|
||||
|
||||
@@ -71,6 +71,29 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly HashSet<Identifier> checkedNonStackableTalents = new();
|
||||
|
||||
/// <summary>
|
||||
/// Checks talents for a given AbilityObject taking into account non-stackable talents.
|
||||
/// </summary>
|
||||
public static void CheckTalentsForCrew(IEnumerable<Character> crew, AbilityEffectType type, AbilityObject abilityObject)
|
||||
{
|
||||
checkedNonStackableTalents.Clear();
|
||||
foreach (Character character in crew)
|
||||
{
|
||||
foreach (CharacterTalent characterTalent in character.CharacterTalents)
|
||||
{
|
||||
if (!characterTalent.Prefab.AbilityEffectsStackWithSameTalent)
|
||||
{
|
||||
if (checkedNonStackableTalents.Contains(characterTalent.Prefab.Identifier)) { continue; }
|
||||
checkedNonStackableTalents.Add(characterTalent.Prefab.Identifier);
|
||||
}
|
||||
|
||||
characterTalent.CheckTalent(type, abilityObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckTalent(AbilityEffectType abilityEffectType, AbilityObject abilityObject)
|
||||
{
|
||||
if (characterAbilityGroupEffectDictionary.TryGetValue(abilityEffectType, out var characterAbilityGroups))
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal abstract class TalentMigration
|
||||
{
|
||||
private readonly Version version;
|
||||
|
||||
private delegate TalentMigration TalentMigrationCtor(Version version, ContentXElement element);
|
||||
|
||||
private static readonly Dictionary<Identifier, TalentMigrationCtor> migrationTemplates =
|
||||
new()
|
||||
{
|
||||
[new Identifier("AddStat")] =
|
||||
static (version, element) => new TalentMigrationAddStat(version, element),
|
||||
|
||||
[new Identifier("UpdateStatIdentifier")] =
|
||||
static (version, element) => new TalentMigrationUpdateStatIdentifier(version, element)
|
||||
};
|
||||
|
||||
public bool TryApply(Version savedVersion, CharacterInfo info)
|
||||
{
|
||||
if (version <= savedVersion) { return false; }
|
||||
Apply(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract void Apply(CharacterInfo info);
|
||||
|
||||
protected TalentMigration(Version targetVersion)
|
||||
{
|
||||
version = targetVersion;
|
||||
}
|
||||
|
||||
public static TalentMigration FromXML(ContentXElement element)
|
||||
{
|
||||
Version? version = XMLExtensions.GetAttributeVersion(element, "version", null);
|
||||
|
||||
if (version is null)
|
||||
{
|
||||
throw new Exception("Talent migration version not defined.");
|
||||
}
|
||||
|
||||
Identifier name = element.Name.ToString().ToIdentifier();
|
||||
|
||||
if (!migrationTemplates.TryGetValue(name, out TalentMigrationCtor? ctor))
|
||||
{
|
||||
throw new Exception($"Unknown talent migration type: {name}.");
|
||||
}
|
||||
|
||||
return ctor(version, element);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migration that adds a missing permanent stat to the character.
|
||||
/// </summary>
|
||||
internal sealed class TalentMigrationAddStat : TalentMigration
|
||||
{
|
||||
[Serialize(StatTypes.None, IsPropertySaveable.Yes)]
|
||||
public StatTypes StatType { get; set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.Yes)]
|
||||
public Identifier StatIdentifier { get; set; }
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.Yes)]
|
||||
public float Value { get; set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool RemoveOnDeath { get; set; }
|
||||
|
||||
public TalentMigrationAddStat(Version targetVersion, ContentXElement element) : base(targetVersion)
|
||||
=> SerializableProperty.DeserializeProperties(this, element);
|
||||
|
||||
protected override void Apply(CharacterInfo info)
|
||||
{
|
||||
info.ChangeSavedStatValue(StatType, Value, StatIdentifier, RemoveOnDeath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Migration that updates permanent stat identifiers.
|
||||
/// </summary>
|
||||
internal class TalentMigrationUpdateStatIdentifier : TalentMigration
|
||||
{
|
||||
[Serialize("", IsPropertySaveable.Yes, "The old identifier to update.")]
|
||||
public Identifier Old { get; set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.Yes, "What to change the old identifier to.")]
|
||||
public Identifier New { get; set; }
|
||||
|
||||
public TalentMigrationUpdateStatIdentifier(Version targetVersion, ContentXElement element) : base(targetVersion)
|
||||
=> SerializableProperty.DeserializeProperties(this, element);
|
||||
|
||||
protected override void Apply(CharacterInfo info)
|
||||
{
|
||||
foreach (SavedStatValue statValue in info.SavedStatValues.Values.SelectMany(static s => s))
|
||||
{
|
||||
if (statValue.StatIdentifier != Old) { continue; }
|
||||
|
||||
statValue.StatIdentifier = New;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
#if CLIENT
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Xml.Linq;
|
||||
#if CLIENT
|
||||
using Microsoft.Xna.Framework;
|
||||
#endif
|
||||
|
||||
@@ -12,6 +15,11 @@ namespace Barotrauma
|
||||
|
||||
public LocalizedString Description { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// When set to false the AbilityEffects of multiple of the same talent will not be checked and only the first one.
|
||||
/// </summary>
|
||||
public bool AbilityEffectsStackWithSameTalent;
|
||||
|
||||
public readonly Sprite Icon;
|
||||
|
||||
#if CLIENT
|
||||
@@ -20,6 +28,8 @@ namespace Barotrauma
|
||||
|
||||
public static readonly PrefabCollection<TalentPrefab> TalentPrefabs = new PrefabCollection<TalentPrefab>();
|
||||
|
||||
public readonly ImmutableHashSet<TalentMigration> Migrations;
|
||||
|
||||
public ContentXElement ConfigElement
|
||||
{
|
||||
get;
|
||||
@@ -32,6 +42,8 @@ namespace Barotrauma
|
||||
|
||||
DisplayName = TextManager.Get($"talentname.{Identifier}").Fallback(Identifier.Value);
|
||||
|
||||
AbilityEffectsStackWithSameTalent = element.GetAttributeBool("abilityeffectsstackwithsametalent", true);
|
||||
|
||||
Identifier nameIdentifier = element.GetAttributeIdentifier("nameidentifier", Identifier.Empty);
|
||||
if (!nameIdentifier.IsEmpty)
|
||||
{
|
||||
@@ -48,6 +60,8 @@ namespace Barotrauma
|
||||
: Option<Color>.None();
|
||||
#endif
|
||||
|
||||
var migrations = ImmutableHashSet.CreateBuilder<TalentMigration>();
|
||||
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -60,9 +74,25 @@ namespace Barotrauma
|
||||
TextManager.ConstructDescription(ref tempDescription, subElement);
|
||||
Description = tempDescription;
|
||||
break;
|
||||
case "migrations":
|
||||
foreach (var migrationElement in subElement.Elements())
|
||||
{
|
||||
try
|
||||
{
|
||||
var migration = TalentMigration.FromXML(migrationElement);
|
||||
migrations.Add(migration);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error while loading talent migration for talent \"{Identifier}\".", e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Migrations = migrations.ToImmutable();
|
||||
|
||||
if (element.GetAttribute("description") != null)
|
||||
{
|
||||
string description = element.GetAttributeString("description", string.Empty);
|
||||
|
||||
Reference in New Issue
Block a user