using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using PkmnLib.Static.Utils;
namespace PkmnLib.Static.Species;
///
/// The data belonging to a Pokemon with certain characteristics.
///
public interface ISpecies
{
///
/// The national dex identifier of the Pokemon.
///
ushort Id { get; }
///
/// The name of the Pokemon.
///
StringKey Name { get; }
///
/// The chance between 0.0 and 1.0 that a Pokemon is female. 0.0 means always male, 1.0 means always female.
/// If less than 0, the Pokemon is genderless.
///
float GenderRate { get; }
///
/// How much experience is required for a level.
///
StringKey GrowthRate { get; }
///
/// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is
/// uncatchable.
///
byte CaptureRate { get; }
///
/// The base happiness of the Pokemon.
///
byte BaseHappiness { get; }
///
/// The forms that belong to this Pokemon.
///
IReadOnlyDictionary Forms { get; }
///
/// The arbitrary flags that can be set on a Pokemon for script use.
///
ImmutableHashSet Flags { get; }
///
/// Gets a form by name.
///
bool TryGetForm(StringKey id, [MaybeNullWhen(false)] out IForm form);
///
/// Gets the form the Pokemon will have by default, if no other form is specified.
///
IForm GetDefaultForm();
///
/// Gets a random gender.
///
Gender GetRandomGender(IRandom rand);
///
/// Check whether the Pokemon has a specific flag set.
///
bool HasFlag(string key);
///
/// The data regarding into which Pokemon this species can evolve, and how.
///
IReadOnlyList EvolutionData { get; }
}
///
public class SpeciesImpl : ISpecies
{
///
public SpeciesImpl(ushort id, StringKey name, float genderRate, StringKey growthRate, byte captureRate,
byte baseHappiness, IReadOnlyDictionary forms, ImmutableHashSet flags,
IReadOnlyList evolutionData)
{
Id = id;
Name = name;
GenderRate = genderRate;
GrowthRate = growthRate;
CaptureRate = captureRate;
BaseHappiness = baseHappiness;
Forms = forms;
Flags = flags;
EvolutionData = evolutionData;
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.");
}
///
public ushort Id { get; }
///
public StringKey Name { get; }
///
public float GenderRate { get; }
///
public StringKey GrowthRate { get; }
///
public byte CaptureRate { get; }
///
public byte BaseHappiness { get; }
///
public IReadOnlyDictionary Forms { get; }
///
public ImmutableHashSet Flags { get; }
///
public IReadOnlyList EvolutionData { get; }
///
public bool TryGetForm(StringKey id, [MaybeNullWhen(false)] out IForm form) => Forms.TryGetValue(id, out form);
///
public IForm GetDefaultForm() => Forms["default"];
///
public Gender GetRandomGender(IRandom rand)
{
if (GenderRate < 0.0f)
return Gender.Genderless;
var v = rand.GetFloat();
return v < GenderRate ? Gender.Female : Gender.Male;
}
///
public bool HasFlag(string key) => Flags.Contains(key);
}