Initial commit
This commit is contained in:
63
PkmnLib.Static/Species/Ability.cs
Normal file
63
PkmnLib.Static/Species/Ability.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Static.Species;
|
||||
|
||||
/// <summary>
|
||||
/// An ability is a passive effect in battle that is attached to a Pokemon.
|
||||
/// </summary>
|
||||
public interface IAbility
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the ability.
|
||||
/// </summary>
|
||||
StringKey Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the script effect of the ability. This should refer to the name of the script that will be executed
|
||||
/// when the ability is triggered.
|
||||
/// </summary>
|
||||
StringKey Effect { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The parameters for the script effect of the ability.
|
||||
/// </summary>
|
||||
IReadOnlyDictionary<StringKey, object> Parameters { get; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public class AbilityImpl : IAbility
|
||||
{
|
||||
/// <inheritdoc cref="AbilityImpl" />
|
||||
public AbilityImpl(StringKey name, StringKey effect, IReadOnlyDictionary<StringKey, object> parameters)
|
||||
{
|
||||
Name = name;
|
||||
Effect = effect;
|
||||
Parameters = parameters;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public StringKey Name { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public StringKey Effect { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyDictionary<StringKey, object> Parameters { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An ability index allows us to find an ability on a form. It combines a bool for whether the
|
||||
/// ability is hidden or not, and then an index of the ability.
|
||||
/// </summary>
|
||||
public readonly record struct AbilityIndex
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the ability we're referring to is a hidden ability.
|
||||
/// </summary>
|
||||
public required bool IsHidden { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The index of the ability.
|
||||
/// </summary>
|
||||
public required byte Index { get; init; }
|
||||
}
|
||||
234
PkmnLib.Static/Species/Evolution.cs
Normal file
234
PkmnLib.Static/Species/Evolution.cs
Normal file
@@ -0,0 +1,234 @@
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Static.Species;
|
||||
|
||||
/// <summary>
|
||||
/// Data about how and into which Pokemon a species can evolve.
|
||||
/// </summary>
|
||||
public interface IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The species that the Pokemon evolves into.
|
||||
/// </summary>
|
||||
StringKey ToSpecies { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when a certain level is reached.
|
||||
/// </summary>
|
||||
public record LevelEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The level at which the Pokemon evolves.
|
||||
/// </summary>
|
||||
public required uint Level { get; init; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when a certain level is reached, and the Pokemon is a specific gender
|
||||
/// </summary>
|
||||
public record LevelGenderEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The level at which the Pokemon evolves.
|
||||
/// </summary>
|
||||
public required uint Level { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The gender the Pokemon needs to have to evolve
|
||||
/// </summary>
|
||||
public required Gender Gender { get; init; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when an item is used on the Pokemon.
|
||||
/// </summary>
|
||||
public record ItemUseEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The item that needs to be used.
|
||||
/// </summary>
|
||||
public required StringKey Item { get; init; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when an item is used on the Pokemon, and the Pokemon is a specific gender
|
||||
/// </summary>
|
||||
public record ItemGenderEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The item that needs to be used.
|
||||
/// </summary>
|
||||
public required StringKey Item { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The gender the Pokemon needs to have to evolve
|
||||
/// </summary>
|
||||
public Gender Gender { get; init; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when an item is held by the Pokemon, and the Pokemon levels up.
|
||||
/// </summary>
|
||||
public record HoldItemEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The item that needs to be held.
|
||||
/// </summary>
|
||||
public required StringKey Item { get; init; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when an item is held by the Pokemon, and the Pokemon levels up, and it's day.
|
||||
/// </summary>
|
||||
public record DayHoldItemEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The item that needs to be held.
|
||||
/// </summary>
|
||||
public required StringKey Item { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when an item is held by the Pokemon, and the Pokemon levels up, and it's night.
|
||||
/// </summary>
|
||||
public record NightHoldItemEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The item that needs to be held.
|
||||
/// </summary>
|
||||
public required StringKey Item { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when the Pokemon knows a certain move, and the Pokemon levels up.
|
||||
/// </summary>
|
||||
public record HasMoveEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the move that needs to be known.
|
||||
/// </summary>
|
||||
public required StringKey MoveName { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when above a certain happiness level, and the Pokemon levels up.
|
||||
/// </summary>
|
||||
public record HappinessEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The happiness level that needs to be reached.
|
||||
/// </summary>
|
||||
public required byte Happiness { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when above a certain happiness level, and the Pokemon levels up, and it's day.
|
||||
/// </summary>
|
||||
public record HappinessDayEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The happiness level that needs to be reached.
|
||||
/// </summary>
|
||||
public required byte Happiness { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when above a certain happiness level, and the Pokemon levels up, and it's night.
|
||||
/// </summary>
|
||||
public record HappinessNightEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The happiness level that needs to be reached.
|
||||
/// </summary>
|
||||
public required byte Happiness { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when traded.
|
||||
/// </summary>
|
||||
public record TradeEvolution : IEvolution
|
||||
{
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when traded with a certain species.
|
||||
/// </summary>
|
||||
public record TradeSpeciesEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The species that needs to be traded with.
|
||||
/// </summary>
|
||||
public required StringKey WithSpecies { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evolves when traded while it's holding a certain item.
|
||||
/// </summary>
|
||||
public record TradeItemEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The item that needs to be held.
|
||||
/// </summary>
|
||||
public required StringKey Item { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom evolution method, implemented by the user.
|
||||
/// </summary>
|
||||
public record CustomEvolution : IEvolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the custom evolution method. This should refer to the name of the script that will be executed.
|
||||
/// </summary>
|
||||
public required StringKey Name { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// The parameters of the custom evolution method.
|
||||
/// </summary>
|
||||
public required IReadOnlyDictionary<StringKey, object> Parameters { get; init; }
|
||||
|
||||
/// < inheritdoc />
|
||||
public required StringKey ToSpecies { get; init; }
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
21
PkmnLib.Static/Species/Gender.cs
Normal file
21
PkmnLib.Static/Species/Gender.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace PkmnLib.Static;
|
||||
|
||||
/// <summary>
|
||||
/// Gender is a Pokemon characteristic.
|
||||
///
|
||||
/// Required for standard pokemon functions, but somewhat controversial nowadays. Consider adding a feature
|
||||
/// that allows for a more progressive gender system for those that want it?
|
||||
/// </summary>
|
||||
public enum Gender : byte
|
||||
{
|
||||
/// The Pokemon has no gender.
|
||||
Genderless,
|
||||
/// <summary>
|
||||
/// The Pokemon is male.
|
||||
/// </summary>
|
||||
Male,
|
||||
/// <summary>
|
||||
/// The Pokemon is female.
|
||||
/// </summary>
|
||||
Female
|
||||
}
|
||||
58
PkmnLib.Static/Species/LearnableMoves.cs
Normal file
58
PkmnLib.Static/Species/LearnableMoves.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Static.Species;
|
||||
|
||||
/// <summary>
|
||||
/// The storage of the moves a Pokemon can learn.
|
||||
/// </summary>
|
||||
public interface ILearnableMoves
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new level move the Pokemon can learn.
|
||||
/// </summary>
|
||||
/// <param name="level">The level the Pokemon learns the move at.</param>
|
||||
/// <param name="move">The move the Pokemon learns.</param>
|
||||
/// <returns>Whether the move was added successfully.</returns>
|
||||
void AddLevelMove(LevelInt level, StringKey move);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all moves a Pokemon can learn when leveling up to a specific level.
|
||||
/// </summary>
|
||||
/// <param name="level">The level the Pokemon is learning moves at.</param>
|
||||
/// <returns>The moves the Pokemon learns at that level.</returns>
|
||||
IReadOnlyList<StringKey> GetLearnedByLevel(LevelInt level);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the distinct moves a Pokemon can learn through leveling up.
|
||||
/// </summary>
|
||||
/// <returns>The moves the Pokemon can learn through leveling up.</returns>
|
||||
IReadOnlyList<StringKey> GetDistinctLevelMoves();
|
||||
}
|
||||
|
||||
public class LearnableMovesImpl : ILearnableMoves
|
||||
{
|
||||
private readonly Dictionary<LevelInt, List<StringKey>> _learnedByLevel = new();
|
||||
private readonly HashSet<StringKey> _distinctLevelMoves = new();
|
||||
|
||||
|
||||
public void AddLevelMove(LevelInt level, StringKey move)
|
||||
{
|
||||
if (!_learnedByLevel.TryGetValue(level, out var value))
|
||||
_learnedByLevel[level] = [move];
|
||||
else
|
||||
value.Add(move);
|
||||
_distinctLevelMoves.Add(move);
|
||||
}
|
||||
|
||||
public IReadOnlyList<StringKey> GetLearnedByLevel(LevelInt level)
|
||||
{
|
||||
if (!_learnedByLevel.TryGetValue(level, out var value))
|
||||
return Array.Empty<StringKey>();
|
||||
return value;
|
||||
}
|
||||
|
||||
public IReadOnlyList<StringKey> GetDistinctLevelMoves()
|
||||
{
|
||||
return _distinctLevelMoves.ToList();
|
||||
}
|
||||
}
|
||||
148
PkmnLib.Static/Species/Species.cs
Normal file
148
PkmnLib.Static/Species/Species.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using PkmnLib.Static.Utils;
|
||||
|
||||
namespace PkmnLib.Static.Species;
|
||||
|
||||
/// <summary>
|
||||
/// The data belonging to a Pokemon with certain characteristics.
|
||||
/// </summary>
|
||||
public interface ISpecies
|
||||
{
|
||||
/// <summary>
|
||||
/// The national dex identifier of the Pokemon.
|
||||
/// </summary>
|
||||
ushort Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the Pokemon.
|
||||
/// </summary>
|
||||
StringKey Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
float GenderRate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// How much experience is required for a level.
|
||||
/// </summary>
|
||||
StringKey GrowthRate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is
|
||||
/// uncatchable.
|
||||
/// </summary>
|
||||
byte CaptureRate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The base happiness of the Pokemon.
|
||||
/// </summary>
|
||||
byte BaseHappiness { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The forms that belong to this Pokemon.
|
||||
/// </summary>
|
||||
IReadOnlyDictionary<StringKey, IForm> Forms { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The arbitrary flags that can be set on a Pokemon for script use.
|
||||
/// </summary>
|
||||
ImmutableHashSet<StringKey> Flags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a form by name.
|
||||
/// </summary>
|
||||
bool TryGetForm(StringKey id, [MaybeNullWhen(false)] out IForm form);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the form the Pokemon will have by default, if no other form is specified.
|
||||
/// </summary>
|
||||
IForm GetDefaultForm();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a random gender.
|
||||
/// </summary>
|
||||
Gender GetRandomGender(IRandom rand);
|
||||
|
||||
/// <summary>
|
||||
/// Check whether the Pokemon has a specific flag set.
|
||||
/// </summary>
|
||||
bool HasFlag(string key);
|
||||
|
||||
/// <summary>
|
||||
/// The data regarding into which Pokemon this species can evolve, and how.
|
||||
/// </summary>
|
||||
IReadOnlyList<IEvolution> EvolutionData { get; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public class SpeciesImpl : ISpecies
|
||||
{
|
||||
/// <inheritdoc cref="SpeciesImpl" />
|
||||
public SpeciesImpl(ushort id, StringKey name, float genderRate, StringKey growthRate, byte captureRate,
|
||||
byte baseHappiness, IReadOnlyDictionary<StringKey, IForm> forms, ImmutableHashSet<StringKey> flags,
|
||||
IReadOnlyList<IEvolution> 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.");
|
||||
}
|
||||
|
||||
/// <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; }
|
||||
|
||||
|
||||
/// <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);
|
||||
}
|
||||
Reference in New Issue
Block a user