219 lines
10 KiB
C#
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; }
|
|
}
|
|
}
|