PkmnLibSharp/PkmnLibSharp/Battling/PokemonBuilder.cs

206 lines
6.9 KiB
C#
Raw Normal View History

2020-07-18 14:49:11 +00:00
using System;
using System.Collections.Generic;
using PkmnLibSharp.Library;
using PkmnLibSharp.Library.Items;
using PkmnLibSharp.Library.Moves;
2020-07-18 14:49:11 +00:00
using Random = PkmnLibSharp.Utilities.Random;
namespace PkmnLibSharp.Battling
{
public abstract class BasePokemonBuilder<TPokemon, TLearnedMove>
where TPokemon : Pokemon
where TLearnedMove :LearnedMove
2020-07-18 14:49:11 +00:00
{
private static readonly Random _defaultRandom = new Random();
2020-08-08 15:07:05 +00:00
protected readonly BattleLibrary Library;
2020-07-18 14:49:11 +00:00
public string Species { get; }
public string Forme { get; private set; } = "default";
public string Nickname { get; private set; } = "";
public string Ability { get; private set; } = "";
public string Nature { get; private set; } = "";
public Gender Gender { get; private set; } = (Gender) (-1);
public uint Identifier { get; private set; } = 0;
public byte Level { get; }
public StatisticSet<byte> IVs;
public StatisticSet<byte> EVs;
public bool? IsForceShiny { get; private set; }
public string? HeldItem { get; private set; }
2020-07-18 14:49:11 +00:00
public List<(string moveName, MoveLearnMethod learnMethod)> LearnedMoves { get; } =
new List<(string moveName, MoveLearnMethod learnMethod)>();
2020-08-08 15:07:05 +00:00
public BasePokemonBuilder(BattleLibrary library, string species, byte level)
2020-07-18 14:49:11 +00:00
{
2020-08-08 15:07:05 +00:00
Library = library;
2020-07-18 14:49:11 +00:00
Species = species;
Level = level;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> WithForme(string forme)
2020-07-18 14:49:11 +00:00
{
Forme = forme;
return this;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> WithGender(Gender gender)
2020-07-18 14:49:11 +00:00
{
Gender = gender;
return this;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> ForceShiny(bool value)
2020-07-18 14:49:11 +00:00
{
IsForceShiny = value;
return this;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> WithHeldItem(string heldItem)
2020-07-18 14:49:11 +00:00
{
HeldItem = heldItem;
return this;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> WithNickname(string nickname)
2020-07-19 10:33:22 +00:00
{
Nickname = nickname;
return this;
}
2020-08-08 16:00:36 +00:00
public BasePokemonBuilder<TPokemon, TLearnedMove> WithNature(string nature)
2020-08-08 16:00:36 +00:00
{
Nature = nature;
return this;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> WithIVs(StatisticSet<byte> ivs)
2020-08-08 16:00:36 +00:00
{
IVs = ivs;
return this;
}
public BasePokemonBuilder<TPokemon, TLearnedMove> WithEVs(StatisticSet<byte> evs)
2020-08-08 16:00:36 +00:00
{
EVs = evs;
return this;
}
2020-07-19 10:33:22 +00:00
public BasePokemonBuilder<TPokemon, TLearnedMove> LearnMove(string moveName, MoveLearnMethod moveLearnMethod)
2020-07-18 14:49:11 +00:00
{
2020-08-08 15:07:05 +00:00
if (LearnedMoves.Count > Library.StaticLibrary.Settings.MaximalMoves)
2020-07-18 14:49:11 +00:00
{
throw new Exception("Too many moves for Pokemon.");
}
LearnedMoves.Add((moveName, moveLearnMethod));
return this;
}
2020-08-08 15:07:05 +00:00
protected byte Coloring;
protected uint Experience;
protected uint Uid;
protected int AbilityIndex;
protected bool HiddenAbility;
2020-07-18 14:49:11 +00:00
2020-08-08 15:07:05 +00:00
protected virtual void PopulateUninitialized(Species species, Forme forme, Random random)
{
Experience = Library.StaticLibrary.GrowthRateLibrary.CalculateExperience(species.GrowthRate, Level);
Uid = random.GetUnsigned(0, uint.MaxValue);
2020-07-18 14:49:11 +00:00
if (Gender == (Gender) (-1))
{
Gender = species.GetRandomGender(random);
}
2020-08-08 15:07:05 +00:00
Coloring = 0;
2020-07-18 14:49:11 +00:00
if (IsForceShiny.HasValue)
{
2020-08-08 15:07:05 +00:00
Coloring = (byte) (IsForceShiny.Value ? 1 : 0);
2020-07-18 14:49:11 +00:00
}
2020-08-08 15:07:05 +00:00
else if (random.Get(Library.StaticLibrary.Settings.ShinyRate) == 0)
2020-07-18 14:49:11 +00:00
{
2020-08-08 15:07:05 +00:00
Coloring = 1;
2020-07-18 14:49:11 +00:00
}
2020-08-08 15:07:05 +00:00
AbilityIndex = 0;
HiddenAbility = false;
2020-07-18 14:49:11 +00:00
if (string.IsNullOrEmpty(Ability))
{
2020-08-08 15:07:05 +00:00
AbilityIndex = forme!.GetRandomAbility(random);
2020-07-18 14:49:11 +00:00
}
else
{
2020-08-08 15:07:05 +00:00
AbilityIndex = forme!.Abilities.IndexOf(Ability);
if (AbilityIndex == -1)
2020-07-18 14:49:11 +00:00
{
2020-08-08 15:07:05 +00:00
AbilityIndex = forme.HiddenAbilities.IndexOf(Ability);
if (AbilityIndex == -1)
2020-07-18 14:49:11 +00:00
{
throw new Exception(
$"Invalid ability '{Ability}' for Pokemon '{species.Name}' and forme '{forme.Name}'.");
}
2020-08-08 15:07:05 +00:00
HiddenAbility = true;
2020-07-18 14:49:11 +00:00
}
}
2020-08-08 15:07:05 +00:00
}
protected abstract TPokemon Finalize(Species species, Forme forme, Item? heldItem,
2020-08-08 15:07:05 +00:00
IReadOnlyCollection<LearnedMove> moves, Nature nature);
2020-07-18 14:49:11 +00:00
protected abstract TLearnedMove CreateLearnedMove(MoveData move, byte maxUses, MoveLearnMethod learnMethod);
public TPokemon Build(Random? random = null)
2020-08-08 15:07:05 +00:00
{
if (!Library.StaticLibrary.SpeciesLibrary.TryGet(Species, out var species))
{
throw new Exception($"Species '{Species}' was not found.");
}
if (!species!.TryGetForme(Forme, out var forme))
{
throw new Exception($"Forme '{Forme}' was not found on species '{Species}'");
}
if (random == null)
{
random = _defaultRandom;
}
2020-08-08 15:07:05 +00:00
Item? heldItem = null;
if (HeldItem != null)
{
if (!Library.StaticLibrary.ItemLibrary.TryGet(HeldItem, out heldItem))
{
throw new Exception($"Item '{HeldItem}' was not found.");
}
}
var moves = new LearnedMove[Library.StaticLibrary.Settings.MaximalMoves];
2020-07-18 14:49:11 +00:00
for (var i = 0; i < LearnedMoves.Count; i++)
{
2020-08-08 15:07:05 +00:00
if (!Library.StaticLibrary.MoveLibrary.TryGet(LearnedMoves[i].moveName, out var move))
2020-07-18 14:49:11 +00:00
{
throw new Exception($"Move '{LearnedMoves[i].moveName}' was not found.");
}
moves[i] = CreateLearnedMove(move!, move!.BaseUsages, LearnedMoves[i].learnMethod);
2020-07-18 14:49:11 +00:00
}
if (string.IsNullOrEmpty(Nature))
{
2020-08-08 15:07:05 +00:00
Nature = Library.StaticLibrary.NatureLibrary.GetRandomNatureName(random);
2020-07-18 14:49:11 +00:00
}
2020-08-08 15:07:05 +00:00
var nature = Library.StaticLibrary.NatureLibrary.GetNature(Nature);
2020-08-17 16:51:07 +00:00
if (Gender == (Gender) (-1))
{
Gender = species.GetRandomGender(random);
}
2020-10-17 16:16:00 +00:00
PopulateUninitialized(species, forme!, random);
2020-08-08 15:07:05 +00:00
return Finalize(species, forme!, heldItem, moves, nature);
2020-07-18 14:49:11 +00:00
}
}
}