PkmnLib.NET/PkmnLib.Static/Species/Species.cs

152 lines
4.3 KiB
C#
Raw Normal View History

2024-07-20 11:51:52 +00:00
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using PkmnLib.Static.Utils;
namespace PkmnLib.Static.Species;
/// <summary>
2024-07-20 14:12:39 +00:00
/// The data belonging to a Pokémon with certain characteristics.
2024-07-20 11:51:52 +00:00
/// </summary>
2024-07-20 14:12:39 +00:00
public interface ISpecies : INamedValue
2024-07-20 11:51:52 +00:00
{
/// <summary>
2024-07-20 14:12:39 +00:00
/// The national dex identifier of the Pokémon.
2024-07-20 11:51:52 +00:00
/// </summary>
ushort Id { get; }
/// <summary>
2024-07-20 14:12:39 +00:00
/// The chance between 0.0 and 1.0 that a Pokémon is female. 0.0 means always male, 1.0 means always female.
/// If less than 0, the Pokémon is genderless.
2024-07-20 11:51:52 +00:00
/// </summary>
float GenderRate { get; }
/// <summary>
/// How much experience is required for a level.
/// </summary>
StringKey GrowthRate { get; }
/// <summary>
2024-07-20 14:12:39 +00:00
/// How hard it is to capture a Pokémon. 255 means this will be always caught, 0 means this is
2024-07-20 11:51:52 +00:00
/// uncatchable.
/// </summary>
byte CaptureRate { get; }
/// <summary>
2024-07-20 14:12:39 +00:00
/// The base happiness of the Pokémon.
2024-07-20 11:51:52 +00:00
/// </summary>
byte BaseHappiness { get; }
/// <summary>
2024-07-20 14:12:39 +00:00
/// The forms that belong to this Pokémon.
2024-07-20 11:51:52 +00:00
/// </summary>
IReadOnlyDictionary<StringKey, IForm> Forms { get; }
/// <summary>
2024-07-20 14:12:39 +00:00
/// The arbitrary flags that can be set on a Pokémon for script use.
2024-07-20 11:51:52 +00:00
/// </summary>
ImmutableHashSet<StringKey> Flags { get; }
/// <summary>
/// Gets a form by name.
/// </summary>
bool TryGetForm(StringKey id, [MaybeNullWhen(false)] out IForm form);
/// <summary>
2024-07-20 14:12:39 +00:00
/// Gets the form the Pokémon will have by default, if no other form is specified.
2024-07-20 11:51:52 +00:00
/// </summary>
IForm GetDefaultForm();
/// <summary>
/// Gets a random gender.
/// </summary>
Gender GetRandomGender(IRandom rand);
/// <summary>
2024-07-20 14:12:39 +00:00
/// Check whether the Pokémon has a specific flag set.
2024-07-20 11:51:52 +00:00
/// </summary>
bool HasFlag(string key);
/// <summary>
2024-07-20 14:12:39 +00:00
/// The data regarding into which Pokémon this species can evolve, and how.
2024-07-20 11:51:52 +00:00
/// </summary>
IReadOnlyList<IEvolution> EvolutionData { get; }
2024-09-30 12:28:26 +00:00
2024-09-30 13:42:25 +00:00
/// <summary>
/// The egg groups the Pokémon belongs to.
/// </summary>
2024-09-30 12:28:26 +00:00
ICollection<StringKey> EggGroups { get; }
2024-07-20 11:51:52 +00:00
}
/// <inheritdoc />
public class SpeciesImpl : ISpecies
{
/// <inheritdoc cref="SpeciesImpl" />
public SpeciesImpl(ushort id, StringKey name, float genderRate, StringKey growthRate, byte captureRate,
2024-09-30 12:28:26 +00:00
byte baseHappiness, IReadOnlyDictionary<StringKey, IForm> forms, IEnumerable<StringKey> flags,
IReadOnlyList<IEvolution> evolutionData, IEnumerable<StringKey> eggGroups)
2024-07-20 11:51:52 +00:00
{
Id = id;
Name = name;
GenderRate = genderRate;
GrowthRate = growthRate;
CaptureRate = captureRate;
BaseHappiness = baseHappiness;
Forms = forms;
2024-09-30 12:28:26 +00:00
Flags = flags.ToImmutableHashSet();
2024-07-20 11:51:52 +00:00
EvolutionData = evolutionData;
2024-09-30 12:28:26 +00:00
EggGroups = eggGroups.ToImmutableHashSet();
2024-07-20 11:51:52 +00:00
if (Forms.Count == 0)
throw new ArgumentException("Species must have at least one form.");
if (!Forms.ContainsKey("default"))
throw new ArgumentException("Species must have a default form.");
}
/// <inheritdoc />
public ushort Id { get; }
/// <inheritdoc />
public StringKey Name { get; }
/// <inheritdoc />
public float GenderRate { get; }
/// <inheritdoc />
public StringKey GrowthRate { get; }
/// <inheritdoc />
public byte CaptureRate { get; }
/// <inheritdoc />
public byte BaseHappiness { get; }
/// <inheritdoc />
public IReadOnlyDictionary<StringKey, IForm> Forms { get; }
/// <inheritdoc />
public ImmutableHashSet<StringKey> Flags { get; }
/// <inheritdoc />
public IReadOnlyList<IEvolution> EvolutionData { get; }
2024-09-30 12:28:26 +00:00
/// <inheritdoc />
public ICollection<StringKey> EggGroups { get; }
2024-07-20 11:51:52 +00:00
/// <inheritdoc />
public bool TryGetForm(StringKey id, [MaybeNullWhen(false)] out IForm form) => Forms.TryGetValue(id, out form);
/// <inheritdoc />
public IForm GetDefaultForm() => Forms["default"];
/// <inheritdoc />
public Gender GetRandomGender(IRandom rand)
{
if (GenderRate < 0.0f)
return Gender.Genderless;
var v = rand.GetFloat();
return v < GenderRate ? Gender.Female : Gender.Male;
}
/// <inheritdoc />
public bool HasFlag(string key) => Flags.Contains(key);
}