Serialization of Pokemon, general fixes
This commit is contained in:
parent
2a0aaed4c3
commit
3214a6f29a
|
@ -40,11 +40,7 @@ public static class AbilityDataLoader
|
|||
var effect = serialized.Effect;
|
||||
var parameters = serialized.Parameters.ToDictionary(x => (StringKey)x.Key, x => x.Value.ToParameter());
|
||||
|
||||
StringKey? effectName;
|
||||
if (effect == null)
|
||||
effectName = null;
|
||||
else
|
||||
effectName = new StringKey(effect);
|
||||
StringKey? effectName = effect == null ? null! : new StringKey(effect);
|
||||
|
||||
var ability = new AbilityImpl(name, effectName, parameters);
|
||||
return ability;
|
||||
|
|
|
@ -31,8 +31,7 @@ public static class ItemDataLoader
|
|||
{
|
||||
if (!Enum.TryParse<ItemCategory>(serialized.ItemType, true, out var itemType))
|
||||
throw new InvalidDataException($"Item type {serialized.ItemType} is not valid for item {serialized.Name}.");
|
||||
BattleItemCategory battleType;
|
||||
Enum.TryParse(serialized.BattleType, true, out battleType);
|
||||
Enum.TryParse(serialized.BattleType, true, out BattleItemCategory battleType);
|
||||
|
||||
return new ItemImpl(serialized.Name, itemType, battleType, serialized.Price,
|
||||
serialized.Flags.Select(x => (StringKey)x).ToImmutableHashSet());
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace PkmnLib.Static;
|
||||
|
@ -49,6 +50,16 @@ public record ImmutableStatisticSet<T>
|
|||
SpecialDefense = specialDefense;
|
||||
Speed = speed;
|
||||
}
|
||||
|
||||
public ImmutableStatisticSet(ImmutableStatisticSet<T> set)
|
||||
{
|
||||
Hp = set.Hp;
|
||||
Attack = set.Attack;
|
||||
Defense = set.Defense;
|
||||
SpecialAttack = set.SpecialAttack;
|
||||
SpecialDefense = set.SpecialDefense;
|
||||
Speed = set.Speed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a statistic from the set.
|
||||
|
@ -72,7 +83,7 @@ public record ImmutableStatisticSet<T>
|
|||
/// A set of statistics that can be changed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public record StatisticSet<T> : ImmutableStatisticSet<T>
|
||||
public record StatisticSet<T> : ImmutableStatisticSet<T>, IEnumerable<T>
|
||||
where T : struct
|
||||
{
|
||||
/// <inheritdoc cref="StatisticSet{T}"/>
|
||||
|
@ -85,6 +96,10 @@ public record StatisticSet<T> : ImmutableStatisticSet<T>
|
|||
defense, specialAttack, specialDefense, speed)
|
||||
{
|
||||
}
|
||||
|
||||
public StatisticSet(StatisticSet<T> set) : base(set)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper function to add two numerics together.
|
||||
|
@ -189,6 +204,23 @@ public record StatisticSet<T> : ImmutableStatisticSet<T>
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
yield return Hp;
|
||||
yield return Attack;
|
||||
yield return Defense;
|
||||
yield return SpecialAttack;
|
||||
yield return SpecialDefense;
|
||||
yield return Speed;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -211,6 +243,10 @@ public abstract record ClampedStatisticSet<T> : StatisticSet<T>
|
|||
SpecialDefense = Clamp(SpecialDefense, Min, Max);
|
||||
Speed = Clamp(Speed, Min, Max);
|
||||
}
|
||||
|
||||
protected ClampedStatisticSet(ClampedStatisticSet<T> set) : base(set)
|
||||
{
|
||||
}
|
||||
|
||||
private static T Clamp(T value, T min, T max)
|
||||
{
|
||||
|
@ -304,6 +340,10 @@ public record IndividualValueStatisticSet : ClampedStatisticSet<byte>
|
|||
byte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
||||
{
|
||||
}
|
||||
|
||||
public IndividualValueStatisticSet(IndividualValueStatisticSet ivs) : base(ivs)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -327,4 +367,8 @@ public record EffortValueStatisticSet : ClampedStatisticSet<byte>
|
|||
byte speed) : base(hp, attack, defense, specialAttack, specialDefense, speed)
|
||||
{
|
||||
}
|
||||
|
||||
public EffortValueStatisticSet(EffortValueStatisticSet evs) : base(evs)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -26,7 +26,10 @@ public readonly record struct StringKey
|
|||
/// <summary>
|
||||
/// Converts a <see cref="string"/> to a <see cref="StringKey"/>.
|
||||
/// </summary>
|
||||
public static implicit operator StringKey(string key) => new(key);
|
||||
public static implicit operator StringKey(string key)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(key) ? default : new StringKey(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="string.ToString()"/>
|
||||
public override string ToString() => _key.ToLowerInvariant();
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Dynamic.Models.Serialized;
|
||||
using PkmnLib.Static;
|
||||
using PkmnLib.Static.Species;
|
||||
using PkmnLib.Tests.Integration;
|
||||
|
||||
namespace PkmnLib.Tests.Dynamic;
|
||||
|
||||
public class SerializationTests
|
||||
{
|
||||
[Test]
|
||||
public void SerializePokemon()
|
||||
{
|
||||
var library = LibraryHelpers.LoadLibrary();
|
||||
Assert.That(library.StaticLibrary.Species.TryGet("bulbasaur", out var species));
|
||||
|
||||
var pokemon = new PokemonImpl(library, species!, species!.GetDefaultForm(), new AbilityIndex()
|
||||
{
|
||||
Index = 0,
|
||||
IsHidden = false,
|
||||
}, 10, 1000, Gender.Male, 0, "hardy");
|
||||
pokemon.LearnMove("tackle", MoveLearnMethod.LevelUp, 255);
|
||||
|
||||
var data = pokemon.Serialize();
|
||||
Assert.That(data, Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data.Species, Is.EqualTo("bulbasaur"));
|
||||
Assert.That(data.Form, Is.EqualTo("default"));
|
||||
Assert.That(data.Ability, Is.EqualTo("overgrow"));
|
||||
Assert.That(data.Level, Is.EqualTo(10));
|
||||
Assert.That(data.PersonalityValue, Is.EqualTo(1000));
|
||||
Assert.That(data.Gender, Is.EqualTo(Gender.Male));
|
||||
Assert.That(data.Experience, Is.EqualTo(560));
|
||||
Assert.That(data.Coloring, Is.EqualTo(0));
|
||||
Assert.That(data.HeldItem, Is.Null);
|
||||
Assert.That(data.CurrentHealth, Is.EqualTo(29));
|
||||
Assert.That(data.Happiness, Is.EqualTo(70));
|
||||
});
|
||||
|
||||
Assert.That(data.Moves, Has.Length.EqualTo(4));
|
||||
Assert.That(data.Moves[0], Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(data.Moves[0]!.MoveName, Is.EqualTo("tackle"));
|
||||
Assert.That(data.Moves[0]!.LearnMethod, Is.EqualTo(MoveLearnMethod.LevelUp));
|
||||
Assert.That(data.Moves[0]!.CurrentPp, Is.EqualTo(35));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializePokemon()
|
||||
{
|
||||
var library = LibraryHelpers.LoadLibrary();
|
||||
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 IndividualValueStatisticSet(20, 20, 20, 20, 20, 20),
|
||||
EffortValues = new EffortValueStatisticSet(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 pokemon = new PokemonImpl(library, data);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(pokemon.Species.Name.ToString(), Is.EqualTo("bulbasaur"));
|
||||
Assert.That(pokemon.Form.Name.ToString(), Is.EqualTo("default"));
|
||||
Assert.That(pokemon.AbilityIndex.Index, Is.EqualTo(0));
|
||||
Assert.That(pokemon.Level, Is.EqualTo(10));
|
||||
Assert.That(pokemon.Experience, Is.EqualTo(560));
|
||||
Assert.That(pokemon.PersonalityValue, Is.EqualTo(1000));
|
||||
Assert.That(pokemon.Gender, Is.EqualTo(Gender.Male));
|
||||
Assert.That(pokemon.Coloring, Is.EqualTo(0));
|
||||
Assert.That(pokemon.HeldItem, Is.Null);
|
||||
Assert.That(pokemon.CurrentHealth, Is.EqualTo(29));
|
||||
Assert.That(pokemon.Happiness, Is.EqualTo(70));
|
||||
Assert.That(pokemon.IndividualValues, Is.EqualTo(new IndividualValueStatisticSet(20, 20, 20, 20, 20, 20)));
|
||||
Assert.That(pokemon.EffortValues, Is.EqualTo(new EffortValueStatisticSet(0, 0, 0, 0, 0, 0)));
|
||||
Assert.That(pokemon.Nature.Name.ToString(), Is.EqualTo("hardy"));
|
||||
Assert.That(pokemon.Nickname, Is.EqualTo("foo"));
|
||||
});
|
||||
Assert.That(pokemon.Moves, Has.Count.EqualTo(4));
|
||||
Assert.That(pokemon.Moves[0], Is.Not.Null);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(pokemon.Moves[0]!.MoveData.Name.ToString(), Is.EqualTo("tackle"));
|
||||
Assert.That(pokemon.Moves[0]!.LearnMethod, Is.EqualTo(MoveLearnMethod.LevelUp));
|
||||
Assert.That(pokemon.Moves[0]!.CurrentPp, Is.EqualTo(23));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
using System.Collections;
|
||||
using System.Text.Json;
|
||||
using PkmnLib.Dataloader;
|
||||
using PkmnLib.Dynamic.Libraries;
|
||||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Plugin.Gen7;
|
||||
using PkmnLib.Static.Libraries;
|
||||
using PkmnLib.Static.Species;
|
||||
using PkmnLib.Tests.Integration.Models;
|
||||
|
||||
|
@ -30,42 +26,10 @@ public class IntegrationTestRunner
|
|||
}
|
||||
}
|
||||
|
||||
private static IDynamicLibrary LoadLibrary()
|
||||
{
|
||||
using var typesFile = File.Open("Data/Types.csv", FileMode.Open);
|
||||
var types = TypeDataLoader.LoadTypeLibrary(typesFile);
|
||||
using var naturesFile = File.Open("Data/Natures.csv", FileMode.Open);
|
||||
var natures = NatureDataLoader.LoadNatureLibrary(naturesFile);
|
||||
using var movesFile = File.Open("Data/Moves.json", FileMode.Open);
|
||||
var moves = MoveDataLoader.LoadMoves(movesFile, types);
|
||||
using var itemsFile = File.Open("Data/Items.json", FileMode.Open);
|
||||
var items = ItemDataLoader.LoadItems(itemsFile);
|
||||
using var abilitiesFile = File.Open("Data/Abilities.json", FileMode.Open);
|
||||
var abilities = AbilityDataLoader.LoadAbilities(abilitiesFile);
|
||||
using var growthRatesFile = File.Open("Data/GrowthRates.json", FileMode.Open);
|
||||
var growthRates = GrowthRateDataLoader.LoadGrowthRates(growthRatesFile);
|
||||
using var speciesFile = File.Open("Data/Pokemon.json", FileMode.Open);
|
||||
var species = SpeciesDataLoader.LoadSpecies(speciesFile, types);
|
||||
|
||||
var staticLibrary = new StaticLibraryImpl(new LibrarySettings()
|
||||
{
|
||||
MaxLevel = 100,
|
||||
ShinyRate = 4096,
|
||||
}, species, moves, abilities, types, natures, growthRates, items);
|
||||
|
||||
var dynamicLibrary = DynamicLibraryImpl.Create(staticLibrary, [
|
||||
new Gen7Plugin(new Gen7PluginConfiguration()
|
||||
{
|
||||
DamageCalculatorHasRandomness = false,
|
||||
}),
|
||||
]);
|
||||
return dynamicLibrary;
|
||||
}
|
||||
|
||||
[TestCaseSource(nameof(TestCases))]
|
||||
public void RunIntegrationTest(IntegrationTestModel test)
|
||||
{
|
||||
var library = LoadLibrary();
|
||||
var library = LibraryHelpers.LoadLibrary();
|
||||
|
||||
var parties = test.BattleSetup.Parties.Select(IBattleParty (x) =>
|
||||
{
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
using PkmnLib.Dataloader;
|
||||
using PkmnLib.Dynamic.Libraries;
|
||||
using PkmnLib.Plugin.Gen7;
|
||||
using PkmnLib.Static.Libraries;
|
||||
|
||||
namespace PkmnLib.Tests.Integration;
|
||||
|
||||
public static class LibraryHelpers
|
||||
{
|
||||
public static IDynamicLibrary LoadLibrary()
|
||||
{
|
||||
using var typesFile = File.Open("Data/Types.csv", FileMode.Open);
|
||||
var types = TypeDataLoader.LoadTypeLibrary(typesFile);
|
||||
using var naturesFile = File.Open("Data/Natures.csv", FileMode.Open);
|
||||
var natures = NatureDataLoader.LoadNatureLibrary(naturesFile);
|
||||
using var movesFile = File.Open("Data/Moves.json", FileMode.Open);
|
||||
var moves = MoveDataLoader.LoadMoves(movesFile, types);
|
||||
using var itemsFile = File.Open("Data/Items.json", FileMode.Open);
|
||||
var items = ItemDataLoader.LoadItems(itemsFile);
|
||||
using var abilitiesFile = File.Open("Data/Abilities.json", FileMode.Open);
|
||||
var abilities = AbilityDataLoader.LoadAbilities(abilitiesFile);
|
||||
using var growthRatesFile = File.Open("Data/GrowthRates.json", FileMode.Open);
|
||||
var growthRates = GrowthRateDataLoader.LoadGrowthRates(growthRatesFile);
|
||||
using var speciesFile = File.Open("Data/Pokemon.json", FileMode.Open);
|
||||
var species = SpeciesDataLoader.LoadSpecies(speciesFile, types);
|
||||
|
||||
var staticLibrary = new StaticLibraryImpl(new LibrarySettings()
|
||||
{
|
||||
MaxLevel = 100,
|
||||
ShinyRate = 4096,
|
||||
}, species, moves, abilities, types, natures, growthRates, items);
|
||||
|
||||
var dynamicLibrary = DynamicLibraryImpl.Create(staticLibrary, [
|
||||
new Gen7Plugin(new Gen7PluginConfiguration()
|
||||
{
|
||||
DamageCalculatorHasRandomness = false,
|
||||
}),
|
||||
]);
|
||||
return dynamicLibrary;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System.Linq;
|
||||
using PkmnLib.Dynamic.Models;
|
||||
using PkmnLib.Dynamic.ScriptHandling;
|
||||
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||
using PkmnLib.Static;
|
||||
|
||||
namespace PkmnLib.Plugin.Gen7.Moves;
|
||||
|
||||
/// <summary>
|
||||
/// The user applies pressure to stress points, sharply boosting one of its or its allies' stats.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Acupressure chooses one of the target's stats at random and raises it by two stages. It can raise either the
|
||||
/// target's Attack, Defense, Special Attack, Special Defense, Speed, accuracy or evasion stat but will not attempt
|
||||
/// to raise a stat that is already maximized, meaning that the move will fail if all stats are maximized
|
||||
/// </remarks>
|
||||
[Script(ScriptCategory.Move, "acupressure")]
|
||||
public class Acupressure : Script
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||
{
|
||||
// If the target has no stats to raise, the move fails
|
||||
if (target.StatBoost.All(s => s == 6))
|
||||
{
|
||||
move.GetHitData(target, hit).Fail();
|
||||
return;
|
||||
}
|
||||
|
||||
// Choose a random stat to raise. 0 is HP, so we start at 1.
|
||||
var stat = (Statistic)move.User.BattleData!.Battle.Random.GetInt(1, (int)Statistic.Speed + 1);
|
||||
target.ChangeStatBoost(stat, 2, false);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue