210 lines
5.8 KiB
C#
210 lines
5.8 KiB
C#
using System.Collections.Immutable;
|
|
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 : INamedValue
|
|
{
|
|
/// <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 Pokémon with this form.
|
|
/// </summary>
|
|
uint BaseExperience { get; }
|
|
|
|
/// <summary>
|
|
/// The normal types a Pokémon 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 Pokémon.
|
|
/// </summary>
|
|
ImmutableStatisticSet<ushort> BaseStats { get; }
|
|
|
|
/// <summary>
|
|
/// The possible abilities a Pokémon with this form can have.
|
|
/// </summary>
|
|
IReadOnlyList<StringKey> Abilities { get; }
|
|
|
|
/// <summary>
|
|
/// The possible hidden abilities a Pokémon with this form can have.
|
|
/// </summary>
|
|
IReadOnlyList<StringKey> HiddenAbilities { get; }
|
|
|
|
/// <summary>
|
|
/// The moves a Pokémon 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>
|
|
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>
|
|
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, ImmutableStatisticSet<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.");
|
|
}
|
|
|
|
/// <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 ImmutableStatisticSet<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 TypeIdentifier GetType(int index)
|
|
{
|
|
if (index < 0 || index >= Types.Count)
|
|
throw new OutOfRangeException("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 StringKey GetAbility(AbilityIndex index)
|
|
{
|
|
var array = index.IsHidden ? HiddenAbilities : Abilities;
|
|
if (index.Index >= array.Count)
|
|
throw new OutOfRangeException("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);
|
|
}
|
|
} |