Serialization of Pokemon, general fixes

This commit is contained in:
2024-09-03 09:31:32 +02:00
parent 2a0aaed4c3
commit 3214a6f29a
11 changed files with 387 additions and 51 deletions

View File

@@ -94,6 +94,12 @@ public class LearnedMoveImpl : ILearnedMove
CurrentPp = MaxPp;
}
public LearnedMoveImpl(IMoveData moveData, MoveLearnMethod learnMethod, byte pp)
: this(moveData, learnMethod)
{
CurrentPp = pp;
}
/// <inheritdoc />
public IMoveData MoveData { get; }

View File

@@ -1,6 +1,7 @@
using JetBrains.Annotations;
using PkmnLib.Dynamic.Events;
using PkmnLib.Dynamic.Libraries;
using PkmnLib.Dynamic.Models.Serialized;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Static;
using PkmnLib.Static.Species;
@@ -79,7 +80,7 @@ public interface IPokemon : IScriptSource
/// <summary>
/// The weight of the Pokemon in kilograms.
/// </summary>
float WeightInKm { get; set; }
float WeightInKg { get; set; }
/// <summary>
/// The height of the Pokemon in meters.
@@ -305,6 +306,7 @@ public interface IPokemon : IScriptSource
void MarkOpponentAsSeen(IPokemon pokemon);
// TODO: (de)serialize
SerializedPokemon Serialize();
}
/// <summary>
@@ -332,7 +334,7 @@ public interface IPokemonBattleData
/// A list of opponents the Pokemon has seen this battle.
/// </summary>
IReadOnlyList<IPokemon> SeenOpponents { get; }
/// <summary>
/// Whether the Pokemon is on the battlefield.
/// </summary>
@@ -362,7 +364,7 @@ public class PokemonImpl : ScriptSource, IPokemon
Types = form.Types.ToList();
Experience = library.StaticLibrary.GrowthRates.CalculateExperience(species.GrowthRate, level);
WeightInKm = form.Weight;
WeightInKg = form.Weight;
HeightInMeters = form.Height;
Happiness = species.BaseHappiness;
if (!library.StaticLibrary.Natures.TryGet(natureName, out var nature))
@@ -373,6 +375,63 @@ public class PokemonImpl : ScriptSource, IPokemon
CurrentHealth = BoostedStats.Hp;
}
public PokemonImpl(IDynamicLibrary library, SerializedPokemon serializedPokemon)
{
Library = library;
if (!library.StaticLibrary.Species.TryGet(serializedPokemon.Species, out var species))
throw new KeyNotFoundException($"Species {serializedPokemon.Species} not found.");
Species = species;
if (!species.TryGetForm(serializedPokemon.Form, out var form))
throw new KeyNotFoundException($"Form {serializedPokemon.Form} not found on species {species.Name}.");
Form = form;
Level = serializedPokemon.Level;
Experience = serializedPokemon.Experience;
PersonalityValue = serializedPokemon.PersonalityValue;
Gender = serializedPokemon.Gender;
Coloring = serializedPokemon.Coloring;
if (serializedPokemon.HeldItem != null)
{
if (!library.StaticLibrary.Items.TryGet(serializedPokemon.HeldItem, out var item))
throw new KeyNotFoundException($"Item {serializedPokemon.HeldItem} not found.");
HeldItem = item;
}
CurrentHealth = serializedPokemon.CurrentHealth;
WeightInKg = form.Weight;
HeightInMeters = form.Height;
Happiness = serializedPokemon.Happiness;
IndividualValues = new IndividualValueStatisticSet(serializedPokemon.IndividualValues);
EffortValues = new EffortValueStatisticSet(serializedPokemon.EffortValues);
if (!library.StaticLibrary.Natures.TryGet(serializedPokemon.Nature, out var nature))
throw new KeyNotFoundException($"Nature {serializedPokemon.Nature} not found.");
Nature = nature;
Nickname = serializedPokemon.Nickname;
if (!library.StaticLibrary.Abilities.TryGet(serializedPokemon.Ability, out var ability))
throw new KeyNotFoundException($"Ability {serializedPokemon.Ability} not found.");
AbilityIndex = form.FindAbilityIndex(ability) ??
throw new KeyNotFoundException(
$"Ability {ability.Name} not found on species {species.Name} form {form.Name}.");
_learnedMoves = serializedPokemon.Moves.Select(move =>
{
if (move == null)
return null;
if (!library.StaticLibrary.Moves.TryGet(move.MoveName, out var moveData))
throw new KeyNotFoundException($"Move {move.MoveName} not found");
return new LearnedMoveImpl(moveData, move.LearnMethod, move.CurrentPp);
}).ToArray();
AllowedExperience = serializedPokemon.AllowedExperience;
IsEgg = serializedPokemon.IsEgg;
Types = form.Types;
RecalculateFlatStats();
if (serializedPokemon.Status != null)
{
if (!library.ScriptResolver.TryResolve(ScriptCategory.Status, serializedPokemon.Status, out var statusScript))
throw new KeyNotFoundException($"Status script {serializedPokemon.Status} not found");
StatusScript.Set(statusScript);
}
}
/// <inheritdoc />
public IDynamicLibrary Library { get; }
@@ -410,7 +469,7 @@ public class PokemonImpl : ScriptSource, IPokemon
public uint CurrentHealth { get; private set; }
/// <inheritdoc />
public float WeightInKm { get; set; }
public float WeightInKg { get; set; }
/// <inheritdoc />
public float HeightInMeters { get; set; }
@@ -712,7 +771,7 @@ public class PokemonImpl : ScriptSource, IPokemon
if (!onBattleField)
{
Volatile.Clear();
WeightInKm = Form.Weight;
WeightInKg = Form.Weight;
HeightInMeters = Form.Height;
}
}
@@ -730,6 +789,9 @@ public class PokemonImpl : ScriptSource, IPokemon
/// <inheritdoc />
public void MarkOpponentAsSeen(IPokemon pokemon) => BattleData?.MarkOpponentAsSeen(pokemon);
/// <inheritdoc />
public SerializedPokemon Serialize() => new(this);
/// <inheritdoc />
public override int ScriptCount
{
@@ -787,6 +849,7 @@ public class PokemonBattleDataImpl : IPokemonBattleData
public byte Position { get; set; }
private readonly List<IPokemon> _seenOpponents = [];
/// <inheritdoc />
public IReadOnlyList<IPokemon> SeenOpponents => _seenOpponents;

View File

@@ -0,0 +1,71 @@
using System.Diagnostics.CodeAnalysis;
using PkmnLib.Static;
using PkmnLib.Static.Species;
namespace PkmnLib.Dynamic.Models.Serialized;
public class SerializedPokemon
{
public SerializedPokemon(){}
[SetsRequiredMembers]
public SerializedPokemon(IPokemon pokemon)
{
Species = pokemon.Species.Name;
Form = pokemon.Form.Name;
Level = pokemon.Level;
Experience = pokemon.Experience;
PersonalityValue = pokemon.PersonalityValue;
Gender = pokemon.Gender;
Coloring = pokemon.Coloring;
HeldItem = pokemon.HeldItem?.Name;
CurrentHealth = pokemon.CurrentHealth;
Happiness = pokemon.Happiness;
IndividualValues = new IndividualValueStatisticSet(pokemon.IndividualValues);
EffortValues = new EffortValueStatisticSet(pokemon.EffortValues);
Nature = pokemon.Nature.Name;
Nickname = pokemon.Nickname;
Ability = pokemon.Form.GetAbility(pokemon.AbilityIndex);
Moves = pokemon.Moves.Select(move =>
{
if (move == null)
return null;
return new SerializedLearnedMove
{
MoveName = move.MoveData.Name,
LearnMethod = move.LearnMethod,
CurrentPp = move.CurrentPp,
};
}).ToArray();
AllowedExperience = pokemon.AllowedExperience;
IsEgg = pokemon.IsEgg;
Status = pokemon.StatusScript.Script?.Name;
}
public required string Species { get; set; }
public required string Form { get; set; }
public LevelInt Level { get; set; }
public uint Experience { get; set; }
public uint PersonalityValue { get; set; }
public Gender Gender { get; set; }
public byte Coloring { get; set; }
public string? HeldItem { get; set; }
public uint CurrentHealth { get; set; }
public byte Happiness { get; set; }
public required IndividualValueStatisticSet IndividualValues { get; set; }
public required EffortValueStatisticSet EffortValues { get; set; }
public required string Nature { get; set; }
public string? Nickname { get; set; }
public required string Ability { get; set; }
public required SerializedLearnedMove?[] Moves { get; set; }
public bool AllowedExperience { get; set; }
public bool IsEgg { get; set; }
public string? Status { get; set; }
}
public class SerializedLearnedMove
{
public required string MoveName { get; set; }
public required MoveLearnMethod LearnMethod { get; set; }
public required byte CurrentPp { get; set; }
}