Begin work on outlining dynamic side

This commit is contained in:
2024-07-27 16:26:45 +02:00
parent 1b501dee7e
commit a251913ebd
44 changed files with 2150 additions and 19 deletions

View File

@@ -1,3 +1,5 @@
using System.Diagnostics.CodeAnalysis;
namespace PkmnLib.Static;
/// <summary>
@@ -79,10 +81,13 @@ public record StatisticSet<T> : ImmutableStatisticSet<T>
{
}
protected T Add(T a, T b) => (T)Convert.ChangeType(Convert.ToInt32(a) + Convert.ToInt32(b), typeof(T));
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 void SetStatistic(Statistic stat, T value)
public virtual void SetStatistic(Statistic stat, T value)
{
switch (stat)
{
@@ -112,64 +117,186 @@ public record StatisticSet<T> : ImmutableStatisticSet<T>
/// <summary>
/// Increases a statistic in the set by a value.
/// </summary>
public void IncreaseStatistic(Statistic stat, T value)
public virtual bool IncreaseStatistic(Statistic stat, T value)
{
switch (stat)
{
case Statistic.Hp:
Hp = (T)Convert.ChangeType(Convert.ToInt32(Hp) + Convert.ToInt32(value), typeof(T));
Hp = Add(Hp, value);
break;
case Statistic.Attack:
Attack = (T)Convert.ChangeType(Convert.ToInt32(Attack) + Convert.ToInt32(value), typeof(T));
Attack = Add(Attack, value);
break;
case Statistic.Defense:
Defense = (T)Convert.ChangeType(Convert.ToInt32(Defense) + Convert.ToInt32(value), typeof(T));
Defense = Add(Defense, value);
break;
case Statistic.SpecialAttack:
SpecialAttack =
(T)Convert.ChangeType(Convert.ToInt32(SpecialAttack) + Convert.ToInt32(value), typeof(T));
SpecialAttack = Add(SpecialAttack, value);
break;
case Statistic.SpecialDefense:
SpecialDefense =
(T)Convert.ChangeType(Convert.ToInt32(SpecialDefense) + Convert.ToInt32(value), typeof(T));
SpecialDefense = Add(SpecialDefense, value);
break;
case Statistic.Speed:
Speed = (T)Convert.ChangeType(Convert.ToInt32(Speed) + Convert.ToInt32(value), typeof(T));
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 void DecreaseStatistic(Statistic stat, T value)
public virtual bool DecreaseStatistic(Statistic stat, T value)
{
switch (stat)
{
case Statistic.Hp:
Hp = (T)Convert.ChangeType(Convert.ToInt32(Hp) - Convert.ToInt32(value), typeof(T));
Hp = Subtract(Hp, value);
break;
case Statistic.Attack:
Attack = (T)Convert.ChangeType(Convert.ToInt32(Attack) - Convert.ToInt32(value), typeof(T));
Attack = Subtract(Attack, value);
break;
case Statistic.Defense:
Defense = (T)Convert.ChangeType(Convert.ToInt32(Defense) - Convert.ToInt32(value), typeof(T));
Defense = Subtract(Defense, value);
break;
case Statistic.SpecialAttack:
SpecialAttack =
(T)Convert.ChangeType(Convert.ToInt32(SpecialAttack) - Convert.ToInt32(value), typeof(T));
SpecialAttack = Subtract(SpecialAttack, value);
break;
case Statistic.SpecialDefense:
SpecialDefense =
(T)Convert.ChangeType(Convert.ToInt32(SpecialDefense) - Convert.ToInt32(value), typeof(T));
SpecialDefense = Subtract(SpecialDefense, value);
break;
case Statistic.Speed:
Speed = (T)Convert.ChangeType(Convert.ToInt32(Speed) - Convert.ToInt32(value), typeof(T));
Speed = Subtract(Speed, value);
break;
default:
throw new ArgumentException("Invalid statistic.");
}
return true;
}
}
/// <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);
}
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(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(byte hp, byte attack, byte defense, byte specialAttack, byte specialDefense,
byte 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 252.
/// </summary>
public record EffortValueStatisticSet : ClampedStatisticSet<byte>
{
/// <inheritdoc />
protected override byte Min => 0;
/// <inheritdoc />
protected override byte Max => 252;
/// <inheritdoc cref="EffortValueStatisticSet"/>
public EffortValueStatisticSet(byte hp, byte attack, byte defense, byte specialAttack, byte specialDefense,
byte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
{
}
}