PkmnLibRSharp/PkmnLibRSharp/DynamicData/PokemonBuilder.cs

165 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using PkmnLibSharp.DynamicData.Libraries;
using PkmnLibSharp.StaticData;
using PkmnLibSharp.Utils;
namespace PkmnLibSharp.DynamicData
{
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;
public PokemonBuilder(DynamicLibrary library, string species, LevelInt level)
{
_library = library;
_species = species;
_level = level;
_randomSeed = DefaultRandom.Next();
_random = new Random(_randomSeed);
}
public PokemonBuilder WithForm(string form)
{
_form = form;
return this;
}
public PokemonBuilder ForceShiny(bool value)
{
_forceShininess = value;
return this;
}
public PokemonBuilder WithGender(Gender gender)
{
_gender = gender;
return this;
}
public PokemonBuilder WithIdentifier(uint identifier)
{
_identifier = identifier;
return this;
}
public PokemonBuilder WithNature(string nature)
{
_natureName = nature;
return this;
}
public PokemonBuilder WithAbility(string ability)
{
_ability = ability;
return this;
}
public PokemonBuilder WithExperience(uint experience)
{
_experience = experience;
return this;
}
public PokemonBuilder LearnMove(string moveName, MoveLearnMethod learnMethod)
{
_moves.Add((moveName, learnMethod));
return this;
}
protected virtual Pokemon Finalize(Species species, Form form, Item? heldItem)
{
var pokemon = new Pokemon(_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;
}
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))
{
using 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);
}
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);
}
}
}