374 lines
11 KiB
C#
374 lines
11 KiB
C#
using System.Collections;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace PkmnLib.Static;
|
|
|
|
/// <summary>
|
|
/// A set of statistics that cannot be changed.
|
|
/// </summary>
|
|
/// <typeparam name="T">The size of the integer to be used</typeparam>
|
|
public record ImmutableStatisticSet<T>
|
|
where T : struct
|
|
{
|
|
/// <summary>
|
|
/// The health points stat value.
|
|
/// </summary>
|
|
public T Hp { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// The physical attack stat value.
|
|
/// </summary>
|
|
public T Attack { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// The physical defense stat value.
|
|
/// </summary>
|
|
public T Defense { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// The special attack stat value.
|
|
/// </summary>
|
|
public T SpecialAttack { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// The special defense stat value.
|
|
/// </summary>
|
|
public T SpecialDefense { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// The speed stat value.
|
|
/// </summary>
|
|
public T Speed { get; protected set; }
|
|
|
|
/// <inheritdoc cref="ImmutableStatisticSet{T}"/>
|
|
public ImmutableStatisticSet(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed)
|
|
{
|
|
Hp = hp;
|
|
Attack = attack;
|
|
Defense = defense;
|
|
SpecialAttack = specialAttack;
|
|
SpecialDefense = specialDefense;
|
|
Speed = speed;
|
|
}
|
|
|
|
public ImmutableStatisticSet(ImmutableStatisticSet<T> set)
|
|
{
|
|
Hp = set.Hp;
|
|
Attack = set.Attack;
|
|
Defense = set.Defense;
|
|
SpecialAttack = set.SpecialAttack;
|
|
SpecialDefense = set.SpecialDefense;
|
|
Speed = set.Speed;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a statistic from the set.
|
|
/// </summary>
|
|
public T GetStatistic(Statistic stat)
|
|
{
|
|
return stat switch
|
|
{
|
|
Statistic.Hp => Hp,
|
|
Statistic.Attack => Attack,
|
|
Statistic.Defense => Defense,
|
|
Statistic.SpecialAttack => SpecialAttack,
|
|
Statistic.SpecialDefense => SpecialDefense,
|
|
Statistic.Speed => Speed,
|
|
_ => throw new ArgumentException("Invalid statistic."),
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A set of statistics that can be changed.
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public record StatisticSet<T> : ImmutableStatisticSet<T>, IEnumerable<T>
|
|
where T : struct
|
|
{
|
|
/// <inheritdoc cref="StatisticSet{T}"/>
|
|
public StatisticSet() : base(default, default, default, default, default, default)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc cref="StatisticSet{T}"/>
|
|
public StatisticSet(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed) : base(hp, attack,
|
|
defense, specialAttack, specialDefense, speed)
|
|
{
|
|
}
|
|
|
|
public StatisticSet(StatisticSet<T> set) : base(set)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper function to add two numerics together.
|
|
/// </summary>
|
|
protected T Add(T a, T b) => (T)Convert.ChangeType(Convert.ToInt32(a) + Convert.ToInt32(b), typeof(T));
|
|
|
|
/// <summary>
|
|
/// Helper function to subtract two numerics.
|
|
/// </summary>
|
|
protected T Subtract(T a, T b) => (T)Convert.ChangeType(Convert.ToInt32(a) - Convert.ToInt32(b), typeof(T));
|
|
|
|
/// <summary>
|
|
/// Modifies a statistic in the set.
|
|
/// </summary>
|
|
public virtual void SetStatistic(Statistic stat, T value)
|
|
{
|
|
switch (stat)
|
|
{
|
|
case Statistic.Hp:
|
|
Hp = value;
|
|
break;
|
|
case Statistic.Attack:
|
|
Attack = value;
|
|
break;
|
|
case Statistic.Defense:
|
|
Defense = value;
|
|
break;
|
|
case Statistic.SpecialAttack:
|
|
SpecialAttack = value;
|
|
break;
|
|
case Statistic.SpecialDefense:
|
|
SpecialDefense = value;
|
|
break;
|
|
case Statistic.Speed:
|
|
Speed = value;
|
|
break;
|
|
default:
|
|
throw new ArgumentException("Invalid statistic.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Increases a statistic in the set by a value.
|
|
/// </summary>
|
|
public virtual bool IncreaseStatistic(Statistic stat, T value)
|
|
{
|
|
switch (stat)
|
|
{
|
|
case Statistic.Hp:
|
|
Hp = Add(Hp, value);
|
|
break;
|
|
case Statistic.Attack:
|
|
Attack = Add(Attack, value);
|
|
break;
|
|
case Statistic.Defense:
|
|
Defense = Add(Defense, value);
|
|
break;
|
|
case Statistic.SpecialAttack:
|
|
SpecialAttack = Add(SpecialAttack, value);
|
|
break;
|
|
case Statistic.SpecialDefense:
|
|
SpecialDefense = Add(SpecialDefense, value);
|
|
break;
|
|
case Statistic.Speed:
|
|
Speed = Add(Speed, value);
|
|
break;
|
|
default:
|
|
throw new ArgumentException("Invalid statistic.");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Decreases a statistic in the set by a value.
|
|
/// </summary>
|
|
public virtual bool DecreaseStatistic(Statistic stat, T value)
|
|
{
|
|
switch (stat)
|
|
{
|
|
case Statistic.Hp:
|
|
Hp = Subtract(Hp, value);
|
|
break;
|
|
case Statistic.Attack:
|
|
Attack = Subtract(Attack, value);
|
|
break;
|
|
case Statistic.Defense:
|
|
Defense = Subtract(Defense, value);
|
|
break;
|
|
case Statistic.SpecialAttack:
|
|
SpecialAttack = Subtract(SpecialAttack, value);
|
|
break;
|
|
case Statistic.SpecialDefense:
|
|
SpecialDefense = Subtract(SpecialDefense, value);
|
|
break;
|
|
case Statistic.Speed:
|
|
Speed = Subtract(Speed, value);
|
|
break;
|
|
default:
|
|
throw new ArgumentException("Invalid statistic.");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public IEnumerator<T> GetEnumerator()
|
|
{
|
|
yield return Hp;
|
|
yield return Attack;
|
|
yield return Defense;
|
|
yield return SpecialAttack;
|
|
yield return SpecialDefense;
|
|
yield return Speed;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A set of statistics that can be changed, but are clamped to a minimum and maximum value.
|
|
/// </summary>
|
|
public abstract record ClampedStatisticSet<T> : StatisticSet<T>
|
|
where T : struct, IComparable<T>
|
|
{
|
|
/// <inheritdoc />
|
|
[SuppressMessage("ReSharper", "VirtualMemberCallInConstructor")]
|
|
protected ClampedStatisticSet(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed) : base(hp,
|
|
attack, defense, specialAttack, specialDefense, speed)
|
|
{
|
|
if (Min.CompareTo(Max) > 0)
|
|
throw new ArgumentException("Minimum value must be less than or equal to maximum value.");
|
|
Hp = Clamp(Hp, Min, Max);
|
|
Attack = Clamp(Attack, Min, Max);
|
|
Defense = Clamp(Defense, Min, Max);
|
|
SpecialAttack = Clamp(SpecialAttack, Min, Max);
|
|
SpecialDefense = Clamp(SpecialDefense, Min, Max);
|
|
Speed = Clamp(Speed, Min, Max);
|
|
}
|
|
|
|
protected ClampedStatisticSet(ClampedStatisticSet<T> set) : base(set)
|
|
{
|
|
}
|
|
|
|
private static T Clamp(T value, T min, T max)
|
|
{
|
|
if (value.CompareTo(min) < 0)
|
|
return min;
|
|
if (value.CompareTo(max) > 0)
|
|
return max;
|
|
|
|
return value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The minimum value for the statistics.
|
|
/// </summary>
|
|
protected abstract T Min { get; }
|
|
|
|
/// <summary>
|
|
/// The maximum value for the statistics.
|
|
/// </summary>
|
|
protected abstract T Max { get; }
|
|
|
|
/// <inheritdoc />
|
|
public override void SetStatistic(Statistic stat, T value) => base.SetStatistic(stat, Clamp(value, Min, Max));
|
|
|
|
/// <inheritdoc />
|
|
public override bool IncreaseStatistic(Statistic stat, T value)
|
|
{
|
|
var current = GetStatistic(stat);
|
|
var newValue = Add(current, value);
|
|
if (newValue.CompareTo(Max) > 0)
|
|
value = Subtract(Max, current);
|
|
if (value.CompareTo(default) == 0)
|
|
return false;
|
|
return base.IncreaseStatistic(stat, value);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override bool DecreaseStatistic(Statistic stat, T value)
|
|
{
|
|
var current = GetStatistic(stat);
|
|
var newValue = Subtract(current, value);
|
|
if (newValue.CompareTo(Min) < 0)
|
|
value = Subtract(current, Min);
|
|
if (value.CompareTo(default) == 0)
|
|
return false;
|
|
return base.DecreaseStatistic(stat, value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A set of statistics that can be changed, but are clamped to a minimum and maximum value of -6 and 6.
|
|
/// </summary>
|
|
public record StatBoostStatisticSet : ClampedStatisticSet<sbyte>
|
|
{
|
|
/// <inheritdoc />
|
|
protected override sbyte Min => -6;
|
|
|
|
/// <inheritdoc />
|
|
protected override sbyte Max => 6;
|
|
|
|
/// <inheritdoc cref="StatBoostStatisticSet"/>
|
|
public StatBoostStatisticSet() : base(0, 0, 0, 0, 0, 0)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc cref="StatBoostStatisticSet"/>
|
|
public StatBoostStatisticSet(sbyte hp, sbyte attack, sbyte defense, sbyte specialAttack, sbyte specialDefense,
|
|
sbyte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A set of statistics that can be changed, but are clamped to a minimum and maximum value of 0 and 31.
|
|
/// </summary>
|
|
public record IndividualValueStatisticSet : ClampedStatisticSet<byte>
|
|
{
|
|
/// <inheritdoc />
|
|
protected override byte Min => 0;
|
|
|
|
/// <inheritdoc />
|
|
protected override byte Max => 31;
|
|
|
|
/// <inheritdoc cref="IndividualValueStatisticSet"/>
|
|
public IndividualValueStatisticSet() : base(0, 0, 0, 0, 0, 0)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc cref="IndividualValueStatisticSet"/>
|
|
public IndividualValueStatisticSet(byte hp, byte attack, byte defense, byte specialAttack, byte specialDefense,
|
|
byte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
|
{
|
|
}
|
|
|
|
public IndividualValueStatisticSet(IndividualValueStatisticSet ivs) : base(ivs)
|
|
{
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// A set of statistics that can be changed, but are clamped to a minimum and maximum value of 0 and 252.
|
|
/// </summary>
|
|
public record EffortValueStatisticSet : ClampedStatisticSet<byte>
|
|
{
|
|
/// <inheritdoc />
|
|
protected override byte Min => 0;
|
|
|
|
/// <inheritdoc />
|
|
protected override byte Max => 252;
|
|
|
|
/// <inheritdoc cref="EffortValueStatisticSet"/>
|
|
public EffortValueStatisticSet() : base(0, 0, 0, 0, 0, 0)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc cref="EffortValueStatisticSet"/>
|
|
public EffortValueStatisticSet(byte hp, byte attack, byte defense, byte specialAttack, byte specialDefense,
|
|
byte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
|
{
|
|
}
|
|
|
|
public EffortValueStatisticSet(EffortValueStatisticSet evs) : base(evs)
|
|
{
|
|
}
|
|
} |