206 lines
7.1 KiB
C#
206 lines
7.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using PkmnLibSharp.DynamicData.Libraries;
|
|
using PkmnLibSharp.StaticData;
|
|
using PkmnLibSharp.Utils;
|
|
|
|
namespace PkmnLibSharp.DynamicData
|
|
{
|
|
/// <summary>
|
|
/// A builder class for creating <see cref="Pokemon"/> instances.
|
|
/// </summary>
|
|
public class PokemonBuilder
|
|
{
|
|
private static readonly Random DefaultRandom = new();
|
|
|
|
private readonly Random _random;
|
|
private readonly int _randomSeed;
|
|
|
|
private readonly DynamicLibrary _library;
|
|
private readonly string _species;
|
|
private string _form = "default";
|
|
private readonly LevelInt _level;
|
|
private bool? _forceShininess;
|
|
private Gender? _gender;
|
|
private uint? _identifier;
|
|
private string? _natureName;
|
|
private string? _ability;
|
|
private uint? _experience;
|
|
private readonly List<(string name, MoveLearnMethod method)> _moves = new();
|
|
|
|
private bool _hiddenAbility;
|
|
private byte _abilityIndex;
|
|
private byte _coloring;
|
|
|
|
/// <inheritdoc cref="PokemonBuilder"/>
|
|
/// <param name="library">The library the Pokemon should use for data</param>
|
|
/// <param name="species">The name of the species of Pokemon</param>
|
|
/// <param name="level">The level the Pokemon should be</param>
|
|
public PokemonBuilder(DynamicLibrary library, string species, LevelInt level)
|
|
{
|
|
_library = library;
|
|
_species = species;
|
|
_level = level;
|
|
_randomSeed = DefaultRandom.Next();
|
|
_random = new Random(_randomSeed);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the name of the form of the Pokemon.
|
|
/// </summary>
|
|
public PokemonBuilder WithForm(string form)
|
|
{
|
|
_form = form;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Force the Pokemon to be shiny or not shiny, instead of letting this be determined randomly.
|
|
/// </summary>
|
|
public PokemonBuilder ForceShiny(bool value)
|
|
{
|
|
_forceShininess = value;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the gender of the Pokemon to a specific value, instead of letting this be determined randomly.
|
|
/// </summary>
|
|
public PokemonBuilder WithGender(Gender gender)
|
|
{
|
|
_gender = gender;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the identifier of the Pokemon to a specific value, instead of letting this be determined randomly.
|
|
/// </summary>
|
|
public PokemonBuilder WithIdentifier(uint identifier)
|
|
{
|
|
_identifier = identifier;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the nature of the Pokemon to a specific value, instead of letting this be determined randomly.
|
|
/// </summary>
|
|
public PokemonBuilder WithNature(string nature)
|
|
{
|
|
_natureName = nature;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the ability of the Pokemon to a specific value, instead of letting this be determined randomly.
|
|
/// </summary>
|
|
public PokemonBuilder WithAbility(string ability)
|
|
{
|
|
_ability = ability;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gives the Pokemon a specific amount of experience. If not set, the experience will be calculated based on
|
|
/// the Pokemon's level and growth rate.
|
|
/// </summary>
|
|
public PokemonBuilder WithExperience(uint experience)
|
|
{
|
|
_experience = experience;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Teaches the Pokemon a move.
|
|
/// </summary>
|
|
public PokemonBuilder LearnMove(string moveName, MoveLearnMethod learnMethod)
|
|
{
|
|
_moves.Add((moveName, learnMethod));
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This method is called after all properties have been set, and will create the Pokemon.
|
|
/// </summary>
|
|
protected virtual Pokemon Finalize(Species species, Form form, Item? heldItem)
|
|
{
|
|
var pokemon = Pokemon.Create(_library, species, form, _hiddenAbility, _abilityIndex, _level,
|
|
_identifier ?? (uint)_random.Next(), _gender!.Value, _coloring, _natureName!);
|
|
if (heldItem != null)
|
|
pokemon.SetHeldItem(heldItem);
|
|
foreach (var move in _moves)
|
|
{
|
|
pokemon.LearnMove(move.name, move.method);
|
|
}
|
|
|
|
return pokemon;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populates any properties that have not been set with random values.
|
|
/// </summary>
|
|
protected virtual void PopulateUninitialized(Species species, Form form, Random random)
|
|
{
|
|
_experience ??= _library.StaticData.GrowthRateLibrary.CalculateExperience(species.GrowthRate, _level);
|
|
_identifier ??= (uint)random.Next();
|
|
_gender ??= species.GetRandomGender((ulong)_randomSeed);
|
|
if (_forceShininess.HasValue)
|
|
{
|
|
_coloring = _forceShininess.Value ? (byte)1 : (byte)0;
|
|
}
|
|
else if (random.Next((int)_library.StaticData.LibrarySettings.ShinyRate) == 0)
|
|
{
|
|
_coloring = 1;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(_ability))
|
|
{
|
|
_hiddenAbility = false;
|
|
_abilityIndex = (byte)_random.Next(0, form.Abilities.Count);
|
|
}
|
|
else
|
|
{
|
|
(_hiddenAbility, _abilityIndex) = GetAbilityIndex(species, form, _ability!);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(_natureName))
|
|
{
|
|
var nature = _library.StaticData.NatureLibrary.GetRandomNature((ulong)_randomSeed);
|
|
_natureName = _library.StaticData.NatureLibrary.GetNatureName(nature);
|
|
}
|
|
}
|
|
|
|
private static (bool, byte) GetAbilityIndex(Species species, Form form, string ability)
|
|
{
|
|
var i = form.Abilities.IndexOf(ability);
|
|
if (i != -1)
|
|
return (false, (byte)i);
|
|
i = form.HiddenAbilities.IndexOf(ability);
|
|
if (i == -1)
|
|
{
|
|
throw new Exception(
|
|
$"Invalid ability '{ability}' for Pokemon '{species.Name}' and forme '{form.Name}'.");
|
|
}
|
|
|
|
return (true, (byte)i);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the Pokemon, based on the properties that have been set.
|
|
/// </summary>
|
|
public Pokemon Build()
|
|
{
|
|
if (!_library.StaticData.SpeciesLibrary.TryGetValue(_species, out var species))
|
|
{
|
|
throw new Exception($"Species '{_species}' was not found.");
|
|
}
|
|
if (!species.TryGetForm(_form, out var form))
|
|
{
|
|
throw new Exception($"Forme '{_form}' was not found on species '{_species}'");
|
|
}
|
|
|
|
PopulateUninitialized(species, form, _random);
|
|
|
|
return Finalize(species, form, null);
|
|
}
|
|
}
|
|
} |