Initial commit
This commit is contained in:
218
PkmnLib.Static/Species/Form.cs
Normal file
218
PkmnLib.Static/Species/Form.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System.Collections.Immutable;
|
||||
using FluentResults;
|
||||
using PkmnLib.Static.Utils;
|
||||
using PkmnLib.Static.Utils.Errors;
|
||||
|
||||
namespace PkmnLib.Static.Species;
|
||||
|
||||
/// <summary>
|
||||
/// A form is a variant of a specific species. A species always has at least one form, but can have
|
||||
/// many more.
|
||||
/// </summary>
|
||||
public interface IForm
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the form.
|
||||
/// </summary>
|
||||
StringKey Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The height of the form in meters.
|
||||
/// </summary>
|
||||
float Height { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The weight of the form in kilograms.
|
||||
/// </summary>
|
||||
float Weight { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The base amount of experience that is gained when beating a Pokemon with this form.
|
||||
/// </summary>
|
||||
uint BaseExperience { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The normal types a Pokemon with this form has.
|
||||
/// </summary>
|
||||
IReadOnlyList<TypeIdentifier> Types { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The inherent values of a form of species that are used for the stats of a Pokemon.
|
||||
/// </summary>
|
||||
StaticStatisticSet<ushort> BaseStats { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The possible abilities a Pokemon with this form can have.
|
||||
/// </summary>
|
||||
IReadOnlyList<StringKey> Abilities { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The possible hidden abilities a Pokemon with this form can have.
|
||||
/// </summary>
|
||||
IReadOnlyList<StringKey> HiddenAbilities { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The moves a Pokemon with this form can learn.
|
||||
/// </summary>
|
||||
ILearnableMoves Moves { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Arbitrary flags can be set on a form for scripting use.
|
||||
/// </summary>
|
||||
ImmutableHashSet<StringKey> Flags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a type of the form at a certain index.
|
||||
/// </summary>
|
||||
Result<TypeIdentifier> GetType(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single base stat value.
|
||||
/// </summary>
|
||||
ushort GetBaseStat(Statistic stat);
|
||||
|
||||
/// <summary>
|
||||
/// Find the index of an ability that can be on this form.
|
||||
/// </summary>
|
||||
AbilityIndex? FindAbilityIndex(IAbility ability);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ability from the form.
|
||||
/// </summary>
|
||||
Result<StringKey> GetAbility(AbilityIndex index);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random ability from the form.
|
||||
/// </summary>
|
||||
StringKey GetRandomAbility(IRandom rand);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random hidden ability from the form.
|
||||
/// </summary>
|
||||
StringKey GetRandomHiddenAbility(IRandom rand);
|
||||
|
||||
/// <summary>
|
||||
/// Check if the form has a specific flag set.
|
||||
/// </summary>
|
||||
bool HasFlag(string key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public class FormImpl : IForm
|
||||
{
|
||||
/// <inheritdoc cref="FormImpl" />
|
||||
public FormImpl(StringKey name, float height, float weight, uint baseExperience,
|
||||
IEnumerable<TypeIdentifier> types, StaticStatisticSet<ushort> baseStats, IEnumerable<StringKey> abilities,
|
||||
IEnumerable<StringKey> hiddenAbilities, ILearnableMoves moves, ImmutableHashSet<StringKey> flags)
|
||||
{
|
||||
Name = name;
|
||||
Height = height;
|
||||
Weight = weight;
|
||||
BaseExperience = baseExperience;
|
||||
Types = [..types];
|
||||
BaseStats = baseStats;
|
||||
Abilities = [..abilities];
|
||||
HiddenAbilities = [..hiddenAbilities];
|
||||
Moves = moves;
|
||||
Flags = flags;
|
||||
|
||||
if (Types.Count == 0)
|
||||
throw new ArgumentException("A form must have at least one type.");
|
||||
if (Abilities.Count == 0)
|
||||
throw new ArgumentException("A form must have at least one ability.");
|
||||
if (HiddenAbilities.Count == 0)
|
||||
throw new ArgumentException("A form must have at least one hidden ability.");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public StringKey Name { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public float Height { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public float Weight { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public uint BaseExperience { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<TypeIdentifier> Types { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public StaticStatisticSet<ushort> BaseStats { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<StringKey> Abilities { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<StringKey> HiddenAbilities { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ILearnableMoves Moves { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ImmutableHashSet<StringKey> Flags { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Result<TypeIdentifier> GetType(int index)
|
||||
{
|
||||
if (index < 0 || index >= Types.Count)
|
||||
return Result.Fail(new OutOfRange("Type", index, Types.Count));
|
||||
return Types[index];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ushort GetBaseStat(Statistic stat) => BaseStats.GetStatistic(stat);
|
||||
|
||||
/// <inheritdoc />
|
||||
public AbilityIndex? FindAbilityIndex(IAbility ability)
|
||||
{
|
||||
for (var i = 0; i < Abilities.Count && i < 255; i++)
|
||||
{
|
||||
if (Abilities[i] == ability.Name)
|
||||
return new AbilityIndex
|
||||
{
|
||||
IsHidden = false,
|
||||
Index = (byte)i
|
||||
};
|
||||
}
|
||||
for (var i = 0; i < HiddenAbilities.Count && i < 255; i++)
|
||||
{
|
||||
if (HiddenAbilities[i] == ability.Name)
|
||||
return new AbilityIndex
|
||||
{
|
||||
IsHidden = true,
|
||||
Index = (byte)i
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Result<StringKey> GetAbility(AbilityIndex index)
|
||||
{
|
||||
var array = index.IsHidden ? HiddenAbilities : Abilities;
|
||||
if (index.Index >= array.Count)
|
||||
return Result.Fail(new OutOfRange("Ability", index.Index, array.Count));
|
||||
return array[index.Index];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public StringKey GetRandomAbility(IRandom rand)
|
||||
{
|
||||
return Abilities[rand.GetInt(Abilities.Count)];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public StringKey GetRandomHiddenAbility(IRandom rand)
|
||||
{
|
||||
return HiddenAbilities[rand.GetInt(HiddenAbilities.Count)];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasFlag(string key)
|
||||
{
|
||||
return Flags.Contains(key);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user