v0.12.0.2
This commit is contained in:
+20
-7
@@ -66,8 +66,13 @@ namespace Barotrauma
|
||||
|
||||
protected static Dictionary<string, Dictionary<string, AnimationParams>> allAnimations = new Dictionary<string, Dictionary<string, AnimationParams>>();
|
||||
|
||||
private float _movementSpeed;
|
||||
[Serialize(1.0f, true), Editable(DecimalCount = 2, MinValueFloat = 0, MaxValueFloat = Ragdoll.MAX_SPEED, ValueStep = 0.1f)]
|
||||
public float MovementSpeed { get; set; }
|
||||
public float MovementSpeed
|
||||
{
|
||||
get => _movementSpeed;
|
||||
set => _movementSpeed = value;
|
||||
}
|
||||
|
||||
[Serialize(1.0f, true, description: "The speed of the \"animation cycle\", i.e. how fast the character takes steps or moves the tail/legs/arms (the outcome depends what the clip is about)"),
|
||||
Editable(MinValueFloat = 0, MaxValueFloat = 10, DecimalCount = 2, ValueStep = 0.01f)]
|
||||
@@ -110,11 +115,10 @@ namespace Barotrauma
|
||||
[Serialize(AnimationType.NotDefined, true), Editable]
|
||||
public virtual AnimationType AnimationType { get; protected set; }
|
||||
|
||||
public static string GetDefaultFileName(string speciesName, AnimationType animType) => $"{speciesName.CapitaliseFirstInvariant()}{animType.ToString()}";
|
||||
public static string GetDefaultFile(string speciesName, AnimationType animType, ContentPackage contentPackage = null)
|
||||
=> Path.Combine(GetFolder(speciesName, contentPackage), $"{GetDefaultFileName(speciesName, animType)}.xml");
|
||||
public static string GetDefaultFileName(string speciesName, AnimationType animType) => $"{speciesName.CapitaliseFirstInvariant()}{animType}";
|
||||
public static string GetDefaultFile(string speciesName, AnimationType animType) => Path.Combine(GetFolder(speciesName), $"{GetDefaultFileName(speciesName, animType)}.xml");
|
||||
|
||||
public static string GetFolder(string speciesName, ContentPackage contentPackage = null)
|
||||
public static string GetFolder(string speciesName)
|
||||
{
|
||||
CharacterPrefab prefab = CharacterPrefab.FindBySpeciesName(speciesName);
|
||||
if (prefab?.XDocument == null)
|
||||
@@ -132,7 +136,7 @@ namespace Barotrauma
|
||||
{
|
||||
folder = Path.Combine(Path.GetDirectoryName(filePath), "Animations");
|
||||
}
|
||||
return folder;
|
||||
return folder.CleanUpPathCrossPlatform(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -163,7 +167,16 @@ namespace Barotrauma
|
||||
return Enum.TryParse(typeString, out AnimationType fileType) && fileType == type;
|
||||
}
|
||||
|
||||
public static T GetDefaultAnimParams<T>(string speciesName, AnimationType animType) where T : AnimationParams, new() => GetAnimParams<T>(speciesName, animType, GetDefaultFileName(speciesName, animType));
|
||||
public static T GetDefaultAnimParams<T>(Character character, AnimationType animType) where T : AnimationParams, new()
|
||||
{
|
||||
string speciesName = character.VariantOf ?? character.SpeciesName;
|
||||
if (character.VariantOf != null && character.Params.VariantFile?.Root?.GetChildElement("animations")?.GetAttributeString("folder", null) != null)
|
||||
{
|
||||
// Use the overridden animations defined in the variant definition file.
|
||||
speciesName = character.SpeciesName;
|
||||
}
|
||||
return GetAnimParams<T>(speciesName, animType, GetDefaultFileName(speciesName, animType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the file name is left null, default file is selected. If fails, will select the default file. Note: Use the filename without the extensions, don't use the full path!
|
||||
|
||||
+8
-8
@@ -7,11 +7,11 @@ namespace Barotrauma
|
||||
{
|
||||
public static FishWalkParams GetDefaultAnimParams(Character character)
|
||||
{
|
||||
return Check(character) ? GetDefaultAnimParams<FishWalkParams>(character.SpeciesName, AnimationType.Walk) : Empty;
|
||||
return Check(character) ? GetDefaultAnimParams<FishWalkParams>(character, AnimationType.Walk) : Empty;
|
||||
}
|
||||
public static FishWalkParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return Check(character) ? GetAnimParams<FishWalkParams>(character.SpeciesName, AnimationType.Walk, fileName) : Empty;
|
||||
return Check(character) ? GetAnimParams<FishWalkParams>(character.VariantOf ?? character.SpeciesName, AnimationType.Walk, fileName) : Empty;
|
||||
}
|
||||
|
||||
protected static FishWalkParams Empty = new FishWalkParams();
|
||||
@@ -23,11 +23,11 @@ namespace Barotrauma
|
||||
{
|
||||
public static FishRunParams GetDefaultAnimParams(Character character)
|
||||
{
|
||||
return Check(character) ? GetDefaultAnimParams<FishRunParams>(character.SpeciesName, AnimationType.Run) : Empty;
|
||||
return Check(character) ? GetDefaultAnimParams<FishRunParams>(character, AnimationType.Run) : Empty;
|
||||
}
|
||||
public static FishRunParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return Check(character) ? GetAnimParams<FishRunParams>(character.SpeciesName, AnimationType.Run, fileName) : Empty;
|
||||
return Check(character) ? GetAnimParams<FishRunParams>(character.VariantOf ?? character.SpeciesName, AnimationType.Run, fileName) : Empty;
|
||||
}
|
||||
|
||||
protected static FishRunParams Empty = new FishRunParams();
|
||||
@@ -37,10 +37,10 @@ namespace Barotrauma
|
||||
|
||||
class FishSwimFastParams : FishSwimParams
|
||||
{
|
||||
public static FishSwimFastParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<FishSwimFastParams>(character.SpeciesName, AnimationType.SwimFast);
|
||||
public static FishSwimFastParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<FishSwimFastParams>(character, AnimationType.SwimFast);
|
||||
public static FishSwimFastParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return GetAnimParams<FishSwimFastParams>(character.SpeciesName, AnimationType.SwimFast, fileName);
|
||||
return GetAnimParams<FishSwimFastParams>(character.VariantOf ?? character.SpeciesName, AnimationType.SwimFast, fileName);
|
||||
}
|
||||
|
||||
public override void StoreSnapshot() => StoreSnapshot<FishSwimFastParams>();
|
||||
@@ -48,10 +48,10 @@ namespace Barotrauma
|
||||
|
||||
class FishSwimSlowParams : FishSwimParams
|
||||
{
|
||||
public static FishSwimSlowParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<FishSwimSlowParams>(character.SpeciesName, AnimationType.SwimSlow);
|
||||
public static FishSwimSlowParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<FishSwimSlowParams>(character, AnimationType.SwimSlow);
|
||||
public static FishSwimSlowParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return GetAnimParams<FishSwimSlowParams>(character.SpeciesName, AnimationType.SwimSlow, fileName);
|
||||
return GetAnimParams<FishSwimSlowParams>(character.VariantOf ?? character.SpeciesName, AnimationType.SwimSlow, fileName);
|
||||
}
|
||||
|
||||
public override void StoreSnapshot() => StoreSnapshot<FishSwimSlowParams>();
|
||||
|
||||
+4
-4
@@ -4,7 +4,7 @@ namespace Barotrauma
|
||||
{
|
||||
class HumanWalkParams : HumanGroundedParams
|
||||
{
|
||||
public static HumanWalkParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanWalkParams>(character.SpeciesName, AnimationType.Walk);
|
||||
public static HumanWalkParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanWalkParams>(character, AnimationType.Walk);
|
||||
public static HumanWalkParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return GetAnimParams<HumanWalkParams>(character.SpeciesName, AnimationType.Walk, fileName);
|
||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
||||
|
||||
class HumanRunParams : HumanGroundedParams
|
||||
{
|
||||
public static HumanRunParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanRunParams>(character.SpeciesName, AnimationType.Run);
|
||||
public static HumanRunParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanRunParams>(character, AnimationType.Run);
|
||||
public static HumanRunParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return GetAnimParams<HumanRunParams>(character.SpeciesName, AnimationType.Run, fileName);
|
||||
@@ -26,7 +26,7 @@ namespace Barotrauma
|
||||
|
||||
class HumanSwimFastParams: HumanSwimParams
|
||||
{
|
||||
public static HumanSwimFastParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanSwimFastParams>(character.SpeciesName, AnimationType.SwimFast);
|
||||
public static HumanSwimFastParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanSwimFastParams>(character, AnimationType.SwimFast);
|
||||
public static HumanSwimFastParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return GetAnimParams<HumanSwimFastParams>(character.SpeciesName, AnimationType.SwimFast, fileName);
|
||||
@@ -38,7 +38,7 @@ namespace Barotrauma
|
||||
|
||||
class HumanSwimSlowParams : HumanSwimParams
|
||||
{
|
||||
public static HumanSwimSlowParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanSwimSlowParams>(character.SpeciesName, AnimationType.SwimSlow);
|
||||
public static HumanSwimSlowParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<HumanSwimSlowParams>(character, AnimationType.SwimSlow);
|
||||
public static HumanSwimSlowParams GetAnimParams(Character character, string fileName = null)
|
||||
{
|
||||
return GetAnimParams<HumanSwimSlowParams>(character.SpeciesName, AnimationType.SwimSlow, fileName);
|
||||
|
||||
@@ -78,6 +78,8 @@ namespace Barotrauma
|
||||
|
||||
public readonly string File;
|
||||
|
||||
public XDocument VariantFile { get; private set; }
|
||||
|
||||
public readonly List<SubParam> SubParams = new List<SubParam>();
|
||||
public readonly List<SoundParams> Sounds = new List<SoundParams>();
|
||||
public readonly List<ParticleParams> BloodEmitters = new List<ParticleParams>();
|
||||
@@ -100,6 +102,32 @@ namespace Barotrauma
|
||||
public bool Load()
|
||||
{
|
||||
bool success = base.Load(File);
|
||||
if (doc.Root.IsCharacterVariant())
|
||||
{
|
||||
VariantFile = doc;
|
||||
var original = CharacterPrefab.FindBySpeciesName(doc.Root.GetAttributeString("inherit", string.Empty));
|
||||
success = Load(original.FilePath);
|
||||
CreateSubParams();
|
||||
TryLoadOverride(this, VariantFile.Root, SerializableProperties);
|
||||
foreach (XElement subElement in VariantFile.Root.Elements())
|
||||
{
|
||||
var matchingParams = SubParams.FirstOrDefault(p => p.Name.Equals(subElement.Name.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
if (matchingParams != null)
|
||||
{
|
||||
TryLoadOverride(matchingParams, subElement, matchingParams.SerializableProperties);
|
||||
// TODO: Make recursive? In practice we don't have to go deeper than this, but the implementation would be a lot cleaner with recursion.
|
||||
foreach (XElement subSubElement in subElement.Elements())
|
||||
{
|
||||
matchingParams = matchingParams.SubParams.FirstOrDefault(p => p.Name.Equals(subSubElement.Name.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
if (matchingParams != null)
|
||||
{
|
||||
TryLoadOverride(matchingParams, subSubElement, matchingParams.SerializableProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
if (string.IsNullOrEmpty(SpeciesName) && MainElement != null)
|
||||
{
|
||||
//backwards compatibility
|
||||
@@ -111,6 +139,8 @@ namespace Barotrauma
|
||||
|
||||
public bool Save(string fileNameWithoutExtension = null)
|
||||
{
|
||||
// Disable saving variants for now. Making it work probably requires more work.
|
||||
if (VariantFile != null) { return false; }
|
||||
Serialize();
|
||||
return base.Save(fileNameWithoutExtension, new XmlWriterSettings
|
||||
{
|
||||
@@ -181,7 +211,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public bool Deserialize(XElement element = null, bool alsoChildren = true, bool recursive = true)
|
||||
private void TryLoadOverride(object parentObject, XElement element, Dictionary<string, SerializableProperty> properties)
|
||||
{
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var matchingAttribute = element.GetAttribute(property.Key);
|
||||
if (matchingAttribute != null)
|
||||
{
|
||||
property.Value.TrySetValue(parentObject, matchingAttribute.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Deserialize(XElement element = null, bool alsoChildren = true, bool recursive = true, bool loadDefaultValues = true)
|
||||
{
|
||||
if (base.Deserialize(element))
|
||||
{
|
||||
@@ -486,17 +528,21 @@ namespace Barotrauma
|
||||
[Serialize(true, true, description: "Enforce aggressive behavior if the creature is spawned as a target of a monster mission."), Editable()]
|
||||
public bool EnforceAggressiveBehaviorForMissions { get; private set; }
|
||||
|
||||
[Serialize(true, true, description: "Should the character target or ignore walls when it's outside the submarine. Doesn't have any effect if no target priority for walls is defined."), Editable()]
|
||||
[Serialize(true, true, description: "Should the character target or ignore walls when it's outside the submarine."), Editable()]
|
||||
public bool TargetOuterWalls { get; private set; }
|
||||
|
||||
[Serialize(false, true, description: "If enabled, the character chooses randomly from the available attacks. The priority is used as a weight for weighted random."), Editable()]
|
||||
public bool RandomAttack { get; private set; }
|
||||
|
||||
[Serialize(false, true, description:"Can the character open doors and hatches without a proper id card? Only applies on humanoids.")]
|
||||
public bool Infiltrate { get; private set; }
|
||||
|
||||
public IEnumerable<TargetParams> Targets => targets;
|
||||
protected readonly List<TargetParams> targets = new List<TargetParams>();
|
||||
|
||||
public AIParams(XElement element, CharacterParams character) : base(element, character)
|
||||
{
|
||||
if (element == null) { return; }
|
||||
element.GetChildElements("target").ForEach(t => TryAddTarget(t, out _));
|
||||
element.GetChildElements("targetpriority").ForEach(t => TryAddTarget(t, out _));
|
||||
}
|
||||
@@ -588,10 +634,13 @@ namespace Barotrauma
|
||||
public bool IgnoreContained { get; set; }
|
||||
|
||||
[Serialize(false, true, description: "Should the target be ignored while the creature is inside. Doesn't matter where the target is."), Editable]
|
||||
public bool IgnoreWhileInside { get; set; }
|
||||
public bool IgnoreInside { get; set; }
|
||||
|
||||
[Serialize(false, true, description: "Should the target be ignored while the creature is outside. Doesn't matter where the target is."), Editable]
|
||||
public bool IgnoreWhileOutside { get; set; }
|
||||
public bool IgnoreOutside { get; set; }
|
||||
|
||||
[Serialize(false, true)]
|
||||
public bool IgnoreIncapacitated { get; set; }
|
||||
|
||||
[Serialize(0f, true, description: "Use to define a distance at which the creature starts the sweeping movement."), Editable(MinValueFloat = 0, MaxValueFloat = 10000, ValueStep = 1, DecimalCount = 0)]
|
||||
public float SweepDistance { get; private set; }
|
||||
@@ -602,6 +651,9 @@ namespace Barotrauma
|
||||
[Serialize(1f, true, description: "How quickly the sweep direction changes. Uses the sine wave pattern."), Editable(MinValueFloat = 0, MaxValueFloat = 10, ValueStep = 0.1f, DecimalCount = 2)]
|
||||
public float SweepSpeed { get; private set; }
|
||||
|
||||
[Serialize(0f, true, description: "How much damage the protected target should take from an attacker before the creature starts defending it.")]
|
||||
public float Threshold { get; private set; }
|
||||
|
||||
public TargetParams(XElement element, CharacterParams character) : base(element, character) { }
|
||||
|
||||
public TargetParams(string tag, AIState state, float priority, CharacterParams character) : base(CreateNewElement(tag, state, priority), character) { }
|
||||
|
||||
@@ -44,14 +44,14 @@ namespace Barotrauma
|
||||
|
||||
protected virtual bool Deserialize(XElement element = null)
|
||||
{
|
||||
element = element ?? MainElement;
|
||||
element ??= MainElement;
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||
return SerializableProperties != null;
|
||||
}
|
||||
|
||||
protected virtual bool Serialize(XElement element = null)
|
||||
{
|
||||
element = element ?? MainElement;
|
||||
element ??= MainElement;
|
||||
if (element == null)
|
||||
{
|
||||
DebugConsole.ThrowError("[EditableParams] The XML element is null!");
|
||||
|
||||
+17
-2
@@ -110,7 +110,7 @@ namespace Barotrauma
|
||||
{
|
||||
folder = Path.Combine(Path.GetDirectoryName(filePath), "Ragdolls") + Path.DirectorySeparatorChar;
|
||||
}
|
||||
return folder;
|
||||
return folder.CleanUpPathCrossPlatform(correctFilenameCase: true);
|
||||
}
|
||||
|
||||
public static T GetDefaultRagdollParams<T>(string speciesName) where T : RagdollParams, new() => GetRagdollParams<T>(speciesName, GetDefaultFileName(speciesName));
|
||||
@@ -136,7 +136,7 @@ namespace Barotrauma
|
||||
string folder = GetFolder(speciesName);
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
var files = Directory.GetFiles(folder);
|
||||
List<string> files = Directory.GetFiles(folder).ToList();
|
||||
if (files.None())
|
||||
{
|
||||
DebugConsole.ThrowError($"[RagdollParams] Could not find any ragdoll files from the folder: {folder}. Using the default ragdoll.");
|
||||
@@ -364,6 +364,21 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private bool variantScaleApplied;
|
||||
public void ApplyVariantScale(XDocument variantFile)
|
||||
{
|
||||
if (variantScaleApplied) { return; }
|
||||
if (variantFile == null) { return; }
|
||||
var scaleMultiplier = variantFile.Root.GetChildElement("ragdoll")?.GetAttributeFloat("scalemultiplier", 1f);
|
||||
if (scaleMultiplier.HasValue)
|
||||
{
|
||||
JointScale *= scaleMultiplier.Value;
|
||||
LimbScale *= scaleMultiplier.Value;
|
||||
}
|
||||
variantScaleApplied = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Memento
|
||||
|
||||
Reference in New Issue
Block a user