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

@@ -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;