Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/Characters/Params/Animation/FishAnimations.cs
2024-04-24 18:09:05 +03:00

219 lines
10 KiB
C#

using Microsoft.Xna.Framework;
using System.Collections.Generic;
namespace Barotrauma
{
class FishWalkParams : FishGroundedParams
{
public static FishWalkParams GetDefaultAnimParams(Character character)
{
return Check(character) ? GetDefaultAnimParams<FishWalkParams>(character, AnimationType.Walk) : Empty;
}
public static FishWalkParams GetAnimParams(Character character, Either<string, ContentPath> file, bool throwErrors = true)
{
return Check(character) ? GetAnimParams<FishWalkParams>(character, AnimationType.Walk, file, throwErrors) : null;
}
protected static readonly FishWalkParams Empty = new FishWalkParams();
public override void StoreSnapshot() => StoreSnapshot<FishWalkParams>();
}
class FishRunParams : FishGroundedParams
{
public static FishRunParams GetDefaultAnimParams(Character character)
{
return Check(character) ? GetDefaultAnimParams<FishRunParams>(character, AnimationType.Run) : Empty;
}
public static FishRunParams GetAnimParams(Character character, Either<string, ContentPath> file, bool throwErrors = true)
{
return Check(character) ? GetAnimParams<FishRunParams>(character, AnimationType.Run, file, throwErrors) : null;
}
protected static readonly FishRunParams Empty = new FishRunParams();
public override void StoreSnapshot() => StoreSnapshot<FishRunParams>();
}
class FishSwimFastParams : FishSwimParams
{
public static FishSwimFastParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<FishSwimFastParams>(character, AnimationType.SwimFast);
public static FishSwimFastParams GetAnimParams(Character character, Either<string, ContentPath> file, bool throwErrors = true)
{
return GetAnimParams<FishSwimFastParams>(character, AnimationType.SwimFast, file, throwErrors);
}
public override void StoreSnapshot() => StoreSnapshot<FishSwimFastParams>();
}
class FishSwimSlowParams : FishSwimParams
{
public static FishSwimSlowParams GetDefaultAnimParams(Character character) => GetDefaultAnimParams<FishSwimSlowParams>(character, AnimationType.SwimSlow);
public static FishSwimSlowParams GetAnimParams(Character character, Either<string, ContentPath> file, bool throwErrors = true)
{
return GetAnimParams<FishSwimSlowParams>(character, AnimationType.SwimSlow, file, throwErrors);
}
public override void StoreSnapshot() => StoreSnapshot<FishSwimSlowParams>();
}
abstract class FishGroundedParams : GroundedMovementParams, IFishAnimation
{
protected static bool Check(Character character)
{
if (!character.AnimController.CanWalk)
{
DebugConsole.ThrowError($"{character.SpeciesName} cannot use run animations!",
contentPackage: character.Prefab.ContentPackage);
return false;
}
return true;
}
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Should the character be flipped depending on which direction it faces. Should usually be enabled on all characters that have distinctive upper and lower sides.")]
public bool Flip { get; set; }
[Serialize(1f, IsPropertySaveable.Yes, description: "Reduces continuous flipping when the character abruptly changes direction."), Editable]
public float FlipCooldown { get; set; }
[Serialize(0.5f, IsPropertySaveable.Yes, description: "How much it takes before the character flips. The timer starts when the character starts to move in the different direction."), Editable]
public float FlipDelay { get; set; }
[Serialize(10.0f, IsPropertySaveable.Yes, description: "How much force is used to move the head to the correct position."), Editable(MinValueFloat = 0, MaxValueFloat = 100)]
public float HeadMoveForce { get; set; }
[Serialize(10.0f, IsPropertySaveable.Yes, description: "How much force is used to move the torso to the correct position."), Editable(MinValueFloat = 0, MaxValueFloat = 100)]
public float TorsoMoveForce { get; set; }
[Serialize(8.0f, IsPropertySaveable.Yes, description: "How much force is used to move the feet to the correct position."), Editable(MinValueFloat = 0, MaxValueFloat = 100)]
public float FootMoveForce { get; set; }
[Serialize(50.0f, IsPropertySaveable.Yes, description: "How much torque is used to rotate the tail to the correct orientation."), Editable(MinValueFloat = 0, MaxValueFloat = 1000, ValueStep = 1)]
public float TailTorque { get; set; }
[Serialize(0.0f, IsPropertySaveable.Yes, description: "Optional torque that's constantly applied to legs."), Editable(MinValueFloat = 0, MaxValueFloat = 1000)]
public float LegTorque { get; set; }
/// <summary>
/// The angle of the collider when standing (i.e. out of water).
/// In degrees.
/// </summary>
[Serialize(0f, IsPropertySaveable.Yes, description: "The angle of the character's collider when standing."), Editable(MinValueFloat = -360, MaxValueFloat = 360)]
public float ColliderStandAngle
{
get => MathHelper.ToDegrees(ColliderStandAngleInRadians);
set => ColliderStandAngleInRadians = MathHelper.ToRadians(value);
}
public float ColliderStandAngleInRadians { get; private set; }
[Serialize(null, IsPropertySaveable.Yes), Editable]
public string FootAngles
{
get => ParseFootAngles(FootAnglesInRadians);
set => SetFootAngles(FootAnglesInRadians, value);
}
/// <summary>
/// Key = limb id, value = angle in radians
/// </summary>
public Dictionary<int, float> FootAnglesInRadians { get; set; } = new Dictionary<int, float>();
/// <summary>
/// In degrees.
/// </summary>
[Serialize(float.NaN, IsPropertySaveable.Yes), Editable(-360f, 360f)]
public float TailAngle
{
get => float.IsNaN(TailAngleInRadians) ? float.NaN : MathHelper.ToDegrees(TailAngleInRadians);
set
{
if (!float.IsNaN(value))
{
TailAngleInRadians = MathHelper.ToRadians(value);
}
}
}
public float TailAngleInRadians { get; private set; } = float.NaN;
}
abstract class FishSwimParams : SwimParams, IFishAnimation
{
[Serialize(false, IsPropertySaveable.Yes, description: "Instead of linear movement (default), use a wave-like movement. Note: WaveAmplitude and WaveLength don't have any effect on this. It's synced with the movement speed."), Editable]
public bool UseSineMovement { get; set; }
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Should the character be flipped depending on which direction it faces. Should usually be enabled on all characters that have distinctive upper and lower sides.")]
public bool Flip { get; set; }
[Serialize(1f, IsPropertySaveable.Yes, description: "Reduces continuous flipping when the character abruptly changes direction."), Editable]
public float FlipCooldown { get; set; }
[Serialize(0.5f, IsPropertySaveable.Yes, description: "How much it takes before the character flips. The timer starts when the character starts to move in the different direction."), Editable]
public float FlipDelay { get; set; }
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "If enabled, the character will simply be mirrored horizontally when it wants to turn around. If disabled, it will rotate itself to face the other direction.")]
public bool Mirror { get; set; }
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Disabling this will make mirroring instantaneous.")]
public bool MirrorLerp { get; set; }
[Serialize(5f, IsPropertySaveable.Yes), Editable]
public float WaveAmplitude { get; set; }
[Serialize(10.0f, IsPropertySaveable.Yes), Editable]
public float WaveLength { get; set; }
[Editable, Serialize(true, IsPropertySaveable.Yes, description: "Should the character face towards the direction it's heading.")]
public bool RotateTowardsMovement { get; set; }
[Serialize(50.0f, IsPropertySaveable.Yes, description: "How much torque is used to rotate the tail to the correct orientation."), Editable(MinValueFloat = 0, MaxValueFloat = 2000, ValueStep = 1)]
public float TailTorque { get; set; }
[Serialize(1f, IsPropertySaveable.Yes, description: "Multiplier applied based on the angle difference between the tail and the main limb. Increasing the value prevents snake-like characters from getting tangled on themselves. Default = 1 (no boost)"), Editable(MinValueFloat = 1, MaxValueFloat = 100)]
public float TailTorqueMultiplier { get; set; }
[Serialize(null, IsPropertySaveable.Yes), Editable]
public string FootAngles
{
get => ParseFootAngles(FootAnglesInRadians);
set => SetFootAngles(FootAnglesInRadians, value);
}
[Serialize(false, IsPropertySaveable.Yes, description: "Should the animation be updated even if the character is not moving?"), Editable]
public bool UpdateAnimationWhenNotMoving { get; set; }
/// <summary>
/// Key = limb id, value = angle in radians
/// </summary>
public Dictionary<int, float> FootAnglesInRadians { get; set; } = new Dictionary<int, float>();
/// <summary>
/// In degrees.
/// </summary>
[Serialize(float.NaN, IsPropertySaveable.Yes), Editable(-360f, 360f)]
public float TailAngle
{
get => float.IsNaN(TailAngleInRadians) ? float.NaN : MathHelper.ToDegrees(TailAngleInRadians);
set
{
if (!float.IsNaN(value))
{
TailAngleInRadians = MathHelper.ToRadians(value);
}
}
}
public float TailAngleInRadians { get; private set; } = float.NaN;
}
interface IFishAnimation
{
string FootAngles { get; set; }
Dictionary<int, float> FootAnglesInRadians { get; set; }
float TailAngle { get; set; }
float TailAngleInRadians { get; }
float TailTorque { get; set; }
bool Flip { get; set; }
float FlipCooldown { get; set; }
float FlipDelay { get; set; }
}
}