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