Fixes for serialization
This commit is contained in:
parent
3214a6f29a
commit
656c208e5f
|
@ -400,8 +400,8 @@ public class PokemonImpl : ScriptSource, IPokemon
|
|||
WeightInKg = form.Weight;
|
||||
HeightInMeters = form.Height;
|
||||
Happiness = serializedPokemon.Happiness;
|
||||
IndividualValues = new IndividualValueStatisticSet(serializedPokemon.IndividualValues);
|
||||
EffortValues = new EffortValueStatisticSet(serializedPokemon.EffortValues);
|
||||
IndividualValues = serializedPokemon.IndividualValues.ToIndividualValueStatisticSet();
|
||||
EffortValues = serializedPokemon.EffortValues.ToEffortValueStatisticSet();
|
||||
if (!library.StaticLibrary.Natures.TryGet(serializedPokemon.Nature, out var nature))
|
||||
throw new KeyNotFoundException($"Nature {serializedPokemon.Nature} not found.");
|
||||
Nature = nature;
|
||||
|
|
|
@ -4,10 +4,17 @@ using PkmnLib.Static.Species;
|
|||
|
||||
namespace PkmnLib.Dynamic.Models.Serialized;
|
||||
|
||||
public class SerializedPokemon
|
||||
/// <summary>
|
||||
/// A serialized Pokémon is a representation of a Pokémon that can be easily serialized and deserialized.
|
||||
/// </summary>
|
||||
public record SerializedPokemon
|
||||
{
|
||||
public SerializedPokemon(){}
|
||||
|
||||
/// <inheritdoc cref="SerializedPokemon"/>
|
||||
public SerializedPokemon()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SerializedPokemon"/>
|
||||
[SetsRequiredMembers]
|
||||
public SerializedPokemon(IPokemon pokemon)
|
||||
{
|
||||
|
@ -21,8 +28,8 @@ public class SerializedPokemon
|
|||
HeldItem = pokemon.HeldItem?.Name;
|
||||
CurrentHealth = pokemon.CurrentHealth;
|
||||
Happiness = pokemon.Happiness;
|
||||
IndividualValues = new IndividualValueStatisticSet(pokemon.IndividualValues);
|
||||
EffortValues = new EffortValueStatisticSet(pokemon.EffortValues);
|
||||
IndividualValues = new SerializedStats(pokemon.IndividualValues);
|
||||
EffortValues = new SerializedStats(pokemon.EffortValues);
|
||||
Nature = pokemon.Nature.Name;
|
||||
Nickname = pokemon.Nickname;
|
||||
Ability = pokemon.Form.GetAbility(pokemon.AbilityIndex);
|
||||
|
@ -41,31 +48,141 @@ public class SerializedPokemon
|
|||
IsEgg = pokemon.IsEgg;
|
||||
Status = pokemon.StatusScript.Script?.Name;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Species"/>
|
||||
public required string Species { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Form"/>
|
||||
public required string Form { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Level"/>
|
||||
public LevelInt Level { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Experience"/>
|
||||
public uint Experience { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.PersonalityValue"/>
|
||||
public uint PersonalityValue { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Gender"/>
|
||||
public Gender Gender { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Coloring"/>
|
||||
public byte Coloring { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.HeldItem"/>
|
||||
public string? HeldItem { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.CurrentHealth"/>
|
||||
public uint CurrentHealth { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Happiness"/>
|
||||
public byte Happiness { get; set; }
|
||||
public required IndividualValueStatisticSet IndividualValues { get; set; }
|
||||
public required EffortValueStatisticSet EffortValues { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.IndividualValues"/>
|
||||
public required SerializedStats IndividualValues { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.EffortValues"/>
|
||||
public required SerializedStats EffortValues { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Nature"/>
|
||||
public required string Nature { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Nickname"/>
|
||||
public string? Nickname { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ability of the Pokémon. Note that this is the ability name, not the ability index, as the ability index might
|
||||
/// change if the order of abilities changes in data.
|
||||
/// </summary>
|
||||
public required string Ability { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.Moves"/>
|
||||
public required SerializedLearnedMove?[] Moves { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.AllowedExperience"/>
|
||||
public bool AllowedExperience { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IPokemon.IsEgg"/>
|
||||
public bool IsEgg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The status of the Pokémon. This is the name of the status script, if any exists.
|
||||
/// </summary>
|
||||
public string? Status { get; set; }
|
||||
}
|
||||
|
||||
public class SerializedLearnedMove
|
||||
/// <summary>
|
||||
/// A serialized learned move is a representation of a learned move that can be easily serialized and deserialized.
|
||||
/// </summary>
|
||||
public record SerializedLearnedMove
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the move.
|
||||
/// </summary>
|
||||
public required string MoveName { get; set; }
|
||||
|
||||
/// <inheritdoc cref="ILearnedMove.LearnMethod"/>
|
||||
public required MoveLearnMethod LearnMethod { get; set; }
|
||||
|
||||
/// <inheritdoc cref="ILearnedMove.CurrentPp"/>
|
||||
public required byte CurrentPp { get; set; }
|
||||
}
|
||||
|
||||
public record SerializedStats
|
||||
{
|
||||
public SerializedStats()
|
||||
{
|
||||
}
|
||||
|
||||
public SerializedStats(ImmutableStatisticSet<byte> stats)
|
||||
{
|
||||
Hp = stats.Hp;
|
||||
Attack = stats.Attack;
|
||||
Defense = stats.Defense;
|
||||
SpecialAttack = stats.SpecialAttack;
|
||||
SpecialDefense = stats.SpecialDefense;
|
||||
Speed = stats.Speed;
|
||||
}
|
||||
|
||||
public SerializedStats(long hp, long attack, long defense, long specialAttack, long specialDefense, long speed)
|
||||
{
|
||||
Hp = hp;
|
||||
Attack = attack;
|
||||
Defense = defense;
|
||||
SpecialAttack = specialAttack;
|
||||
SpecialDefense = specialDefense;
|
||||
Speed = speed;
|
||||
}
|
||||
|
||||
public long Hp { get; set; }
|
||||
public long Attack { get; set; }
|
||||
public long Defense { get; set; }
|
||||
public long SpecialAttack { get; set; }
|
||||
public long SpecialDefense { get; set; }
|
||||
public long Speed { get; set; }
|
||||
|
||||
public IndividualValueStatisticSet ToIndividualValueStatisticSet()
|
||||
{
|
||||
if (Hp < 0 || Attack < 0 || Defense < 0 || SpecialAttack < 0 || SpecialDefense < 0 || Speed < 0)
|
||||
throw new InvalidOperationException("Stats cannot be negative.");
|
||||
if (Hp > byte.MaxValue || Attack > byte.MaxValue || Defense > byte.MaxValue || SpecialAttack > byte.MaxValue ||
|
||||
SpecialDefense > byte.MaxValue || Speed > byte.MaxValue)
|
||||
throw new InvalidOperationException("Stats cannot be higher than 255.");
|
||||
|
||||
return new IndividualValueStatisticSet((byte)Hp, (byte)Attack, (byte)Defense, (byte)SpecialAttack,
|
||||
(byte)SpecialDefense, (byte)Speed);
|
||||
}
|
||||
|
||||
public EffortValueStatisticSet ToEffortValueStatisticSet()
|
||||
{
|
||||
if (Hp < 0 || Attack < 0 || Defense < 0 || SpecialAttack < 0 || SpecialDefense < 0 || Speed < 0)
|
||||
throw new InvalidOperationException("Stats cannot be negative.");
|
||||
if (Hp > byte.MaxValue || Attack > byte.MaxValue || Defense > byte.MaxValue || SpecialAttack > byte.MaxValue ||
|
||||
SpecialDefense > byte.MaxValue || Speed > byte.MaxValue)
|
||||
throw new InvalidOperationException("Stats cannot be higher than 255.");
|
||||
|
||||
return new EffortValueStatisticSet((byte)Hp, (byte)Attack, (byte)Defense, (byte)SpecialAttack,
|
||||
(byte)SpecialDefense, (byte)Speed);
|
||||
}
|
||||
}
|
|
@ -334,7 +334,7 @@ public record IndividualValueStatisticSet : ClampedStatisticSet<byte>
|
|||
public IndividualValueStatisticSet() : base(0, 0, 0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc cref="IndividualValueStatisticSet"/>
|
||||
public IndividualValueStatisticSet(byte hp, byte attack, byte defense, byte specialAttack, byte specialDefense,
|
||||
byte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Text.Json;
|
||||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Dynamic.Models.Serialized;
|
||||
using PkmnLib.Static;
|
||||
|
@ -65,8 +66,8 @@ public class SerializationTests
|
|||
HeldItem = null,
|
||||
CurrentHealth = 29,
|
||||
Happiness = 70,
|
||||
IndividualValues = new IndividualValueStatisticSet(20, 20, 20, 20, 20, 20),
|
||||
EffortValues = new EffortValueStatisticSet(0, 0, 0, 0, 0, 0),
|
||||
IndividualValues = new SerializedStats(20, 20, 20, 20, 20, 20),
|
||||
EffortValues = new SerializedStats(0, 0, 0, 0, 0, 0),
|
||||
Nature = "hardy",
|
||||
Nickname = "foo",
|
||||
Moves = new[]
|
||||
|
@ -112,4 +113,70 @@ public class SerializationTests
|
|||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializedPokemonToJson()
|
||||
{
|
||||
var data = new SerializedPokemon
|
||||
{
|
||||
Species = "bulbasaur",
|
||||
Form = "default",
|
||||
Ability = "overgrow",
|
||||
Level = 10,
|
||||
Experience = 560,
|
||||
PersonalityValue = 1000,
|
||||
Gender = Gender.Male,
|
||||
Coloring = 0,
|
||||
HeldItem = null,
|
||||
CurrentHealth = 29,
|
||||
Happiness = 70,
|
||||
IndividualValues = new SerializedStats(20, 20, 20, 20, 20, 20),
|
||||
EffortValues = new SerializedStats(0, 0, 0, 0, 0, 0),
|
||||
Nature = "hardy",
|
||||
Nickname = "foo",
|
||||
Moves = new[]
|
||||
{
|
||||
new SerializedLearnedMove
|
||||
{
|
||||
MoveName = "tackle",
|
||||
LearnMethod = MoveLearnMethod.LevelUp,
|
||||
CurrentPp = 23,
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
},
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(data);
|
||||
var deserialized = JsonSerializer.Deserialize<SerializedPokemon>(json);
|
||||
Assert.That(deserialized, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(deserialized!.Species, Is.EqualTo("bulbasaur"));
|
||||
Assert.That(deserialized!.Form, Is.EqualTo("default"));
|
||||
Assert.That(deserialized!.Ability, Is.EqualTo("overgrow"));
|
||||
Assert.That(deserialized!.Level, Is.EqualTo(10));
|
||||
Assert.That(deserialized!.Experience, Is.EqualTo(560));
|
||||
Assert.That(deserialized!.PersonalityValue, Is.EqualTo(1000));
|
||||
Assert.That(deserialized!.Gender, Is.EqualTo(Gender.Male));
|
||||
Assert.That(deserialized!.Coloring, Is.EqualTo(0));
|
||||
Assert.That(deserialized!.HeldItem, Is.Null);
|
||||
Assert.That(deserialized!.CurrentHealth, Is.EqualTo(29));
|
||||
Assert.That(deserialized!.Happiness, Is.EqualTo(70));
|
||||
Assert.That(deserialized!.IndividualValues, Is.EqualTo(new SerializedStats(20, 20, 20, 20, 20, 20)));
|
||||
Assert.That(deserialized!.EffortValues, Is.EqualTo(new SerializedStats(0, 0, 0, 0, 0, 0)));
|
||||
Assert.That(deserialized!.Nature, Is.EqualTo("hardy"));
|
||||
Assert.That(deserialized!.Nickname, Is.EqualTo("foo"));
|
||||
});
|
||||
|
||||
Assert.That(deserialized!.Moves, Has.Length.EqualTo(4));
|
||||
Assert.That(deserialized!.Moves[0], Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(deserialized!.Moves[0]!.MoveName, Is.EqualTo("tackle"));
|
||||
Assert.That(deserialized!.Moves[0]!.LearnMethod, Is.EqualTo(MoveLearnMethod.LevelUp));
|
||||
Assert.That(deserialized!.Moves[0]!.CurrentPp, Is.EqualTo(23));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue