A load more work on FFI
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
3369696956
commit
2448f3bfb5
|
@ -6,7 +6,7 @@ namespace PkmnLibSharp.DynamicData.Libraries
|
||||||
{
|
{
|
||||||
public abstract class BattleStatCalculator : ExternPointer<object>
|
public abstract class BattleStatCalculator : ExternPointer<object>
|
||||||
{
|
{
|
||||||
public BattleStatCalculator(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner){}
|
protected BattleStatCalculator(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner){}
|
||||||
|
|
||||||
protected override object CreateCache() => new();
|
protected override object CreateCache() => new();
|
||||||
|
|
||||||
|
|
|
@ -8,17 +8,26 @@ namespace PkmnLibSharp.DynamicData.Libraries
|
||||||
{
|
{
|
||||||
public class CacheData
|
public class CacheData
|
||||||
{
|
{
|
||||||
|
public StaticData.Libraries.StaticData? StaticData { get; internal set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DynamicLibrary(IdentifiablePointer ptr) : base(ptr, false) {}
|
internal DynamicLibrary(IdentifiablePointer ptr) : base(ptr, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public DynamicLibrary(StaticData.Libraries.StaticData staticData, BattleStatCalculator statCalculator,
|
public DynamicLibrary(StaticData.Libraries.StaticData staticData, BattleStatCalculator statCalculator,
|
||||||
DamageLibrary damageLibrary, MiscLibrary miscLibrary, ScriptResolver scriptResolver) : base(
|
DamageLibrary damageLibrary, MiscLibrary miscLibrary, ScriptResolver scriptResolver) : base(
|
||||||
Interface.dynamic_library_new(staticData.Ptr, statCalculator.Ptr, damageLibrary.Ptr, miscLibrary.Ptr,
|
Interface.dynamic_library_new(staticData.TakeOwnershipAndInvalidate(),
|
||||||
scriptResolver.Ptr), true)
|
statCalculator.TakeOwnershipAndInvalidate(), damageLibrary.TakeOwnershipAndInvalidate(),
|
||||||
|
miscLibrary.TakeOwnershipAndInvalidate(), scriptResolver.TakeOwnershipAndInvalidate()), true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StaticData.Libraries.StaticData StaticData =>
|
||||||
|
Cache.StaticData ??=
|
||||||
|
new StaticData.Libraries.StaticData(Interface.dynamic_library_get_static_data(Ptr), false);
|
||||||
|
|
||||||
|
|
||||||
protected override CacheData CreateCache() => new();
|
protected override CacheData CreateCache() => new();
|
||||||
protected override void Destructor() => Interface.dynamic_library_drop(Ptr);
|
protected override void Destructor() => Interface.dynamic_library_drop(Ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLibSharp.DynamicData.Libraries;
|
||||||
|
using PkmnLibSharp.StaticData;
|
||||||
|
using PkmnLibSharp.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLibSharp.DynamicData
|
||||||
|
{
|
||||||
|
public class PokemonBuilder
|
||||||
|
{
|
||||||
|
private static readonly Random DefaultRandom = new();
|
||||||
|
|
||||||
|
private readonly Random _random;
|
||||||
|
private readonly int _randomSeed;
|
||||||
|
|
||||||
|
private readonly DynamicLibrary _library;
|
||||||
|
private readonly string _species;
|
||||||
|
private string _form = "default";
|
||||||
|
private readonly LevelInt _level;
|
||||||
|
private bool? _forceShininess;
|
||||||
|
private Gender? _gender;
|
||||||
|
private uint? _identifier;
|
||||||
|
private string? _natureName;
|
||||||
|
private string? _ability;
|
||||||
|
private uint? _experience;
|
||||||
|
private readonly List<(string name, MoveLearnMethod method)> _moves = new();
|
||||||
|
|
||||||
|
private bool _hiddenAbility;
|
||||||
|
private byte _abilityIndex;
|
||||||
|
private byte _coloring;
|
||||||
|
|
||||||
|
public PokemonBuilder(DynamicLibrary library, string species, LevelInt level)
|
||||||
|
{
|
||||||
|
_library = library;
|
||||||
|
_species = species;
|
||||||
|
_level = level;
|
||||||
|
_randomSeed = DefaultRandom.Next();
|
||||||
|
_random = new Random(_randomSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder WithForm(string form)
|
||||||
|
{
|
||||||
|
_form = form;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder ForceShiny(bool value)
|
||||||
|
{
|
||||||
|
_forceShininess = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder WithGender(Gender gender)
|
||||||
|
{
|
||||||
|
_gender = gender;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder WithIdentifier(uint identifier)
|
||||||
|
{
|
||||||
|
_identifier = identifier;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder WithNature(string nature)
|
||||||
|
{
|
||||||
|
_natureName = nature;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder WithAbility(string ability)
|
||||||
|
{
|
||||||
|
_ability = ability;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder WithExperience(uint experience)
|
||||||
|
{
|
||||||
|
_experience = experience;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PokemonBuilder LearnMove(string moveName, MoveLearnMethod learnMethod)
|
||||||
|
{
|
||||||
|
_moves.Add((moveName, learnMethod));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual Pokemon Finalize(Species species, Form form, Item? heldItem)
|
||||||
|
{
|
||||||
|
var pokemon = new Pokemon(_library, species, form, _hiddenAbility, _abilityIndex, _level,
|
||||||
|
_identifier ?? (uint)_random.Next(), _gender!.Value, _coloring, _natureName!);
|
||||||
|
if (heldItem != null)
|
||||||
|
pokemon.SetHeldItem(heldItem);
|
||||||
|
foreach (var move in _moves)
|
||||||
|
{
|
||||||
|
pokemon.LearnMove(move.name, move.method);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pokemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void PopulateUninitialized(Species species, Form form, Random random)
|
||||||
|
{
|
||||||
|
_experience ??= _library.StaticData.GrowthRateLibrary.CalculateExperience(species.GrowthRate, _level);
|
||||||
|
_identifier ??= (uint)random.Next();
|
||||||
|
_gender ??= species.GetRandomGender((ulong)_randomSeed);
|
||||||
|
if (_forceShininess.HasValue)
|
||||||
|
{
|
||||||
|
_coloring = _forceShininess.Value ? (byte)1 : (byte)0;
|
||||||
|
}
|
||||||
|
else if (random.Next((int)_library.StaticData.LibrarySettings.ShinyRate) == 0)
|
||||||
|
{
|
||||||
|
_coloring = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(_ability))
|
||||||
|
{
|
||||||
|
_hiddenAbility = false;
|
||||||
|
_abilityIndex = (byte)_random.Next(0, form.Abilities.Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(_hiddenAbility, _abilityIndex) = GetAbilityIndex(species, form, _ability!);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(_natureName))
|
||||||
|
{
|
||||||
|
using var nature = _library.StaticData.NatureLibrary.GetRandomNature((ulong)_randomSeed);
|
||||||
|
_natureName = _library.StaticData.NatureLibrary.GetNatureName(nature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (bool, byte) GetAbilityIndex(Species species, Form form, string ability)
|
||||||
|
{
|
||||||
|
var i = form.Abilities.IndexOf(ability);
|
||||||
|
if (i != -1)
|
||||||
|
return (false, (byte)i);
|
||||||
|
i = form.HiddenAbilities.IndexOf(ability);
|
||||||
|
if (i == -1)
|
||||||
|
{
|
||||||
|
throw new Exception(
|
||||||
|
$"Invalid ability '{ability}' for Pokemon '{species.Name}' and forme '{form.Name}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true, (byte)i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pokemon Build()
|
||||||
|
{
|
||||||
|
if (!_library.StaticData.SpeciesLibrary.TryGetValue(_species, out var species))
|
||||||
|
{
|
||||||
|
throw new Exception($"Species '{_species}' was not found.");
|
||||||
|
}
|
||||||
|
if (!species.TryGetForm(_form, out var form))
|
||||||
|
{
|
||||||
|
throw new Exception($"Forme '{_form}' was not found on species '{_species}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
PopulateUninitialized(species, form, _random);
|
||||||
|
|
||||||
|
return Finalize(species, form, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,5 +18,11 @@ namespace PkmnLibSharp.FFI.DynamicData.Libraries
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
internal static extern void dynamic_library_drop(IntPtr dynamicLibrary);
|
internal static extern void dynamic_library_drop(IntPtr dynamicLibrary);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The static data is the immutable storage data for this library.
|
||||||
|
/// </summary>
|
||||||
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
|
internal static extern IdentifiablePointer dynamic_library_get_static_data(IntPtr dynamicLibrary);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,12 +7,16 @@ namespace PkmnLibSharp.FFI.StaticData.Libraries
|
||||||
internal static class LibrarySettings
|
internal static class LibrarySettings
|
||||||
{
|
{
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
internal static extern IdentifiablePointer library_settings_new(LevelInt maxLevel);
|
internal static extern IdentifiablePointer library_settings_new(LevelInt maxLevel, uint shinyRate);
|
||||||
|
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
internal static extern void library_settings_drop(IntPtr ptr);
|
internal static extern void library_settings_drop(IntPtr ptr);
|
||||||
|
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
internal static extern LevelInt library_settings_maximum_level(IntPtr ptr);
|
internal static extern LevelInt library_settings_maximum_level(IntPtr ptr);
|
||||||
|
|
||||||
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
|
internal static extern uint library_settings_shiny_rate(IntPtr ptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,6 +17,9 @@ namespace PkmnLibSharp.FFI.StaticData.Libraries
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
internal static extern IdentifiablePointer nature_library_get_nature(IntPtr ptr, IntPtr name);
|
internal static extern IdentifiablePointer nature_library_get_nature(IntPtr ptr, IntPtr name);
|
||||||
|
|
||||||
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
|
internal static extern IdentifiablePointer nature_library_get_random_nature(IntPtr ptr, ulong seed);
|
||||||
|
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||||
internal static extern IntPtr nature_library_get_nature_name(IntPtr ptr, IntPtr nature);
|
internal static extern IntPtr nature_library_get_nature_name(IntPtr ptr, IntPtr nature);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using PkmnLibSharp.StaticData;
|
||||||
|
|
||||||
namespace PkmnLibSharp.FFI.StaticData
|
namespace PkmnLibSharp.FFI.StaticData
|
||||||
{
|
{
|
||||||
|
@ -33,5 +34,8 @@ namespace PkmnLibSharp.FFI.StaticData
|
||||||
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
internal static extern IdentifiablePointer species_get_form(IntPtr ptr, IntPtr name);
|
internal static extern IdentifiablePointer species_get_form(IntPtr ptr, IntPtr name);
|
||||||
|
|
||||||
|
[DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
internal static extern Gender species_get_random_gender(IntPtr ptr, ulong seed);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
|
||||||
<RootNamespace>PkmnLibSharp</RootNamespace>
|
<RootNamespace>PkmnLibSharp</RootNamespace>
|
||||||
<LangVersion>11</LangVersion>
|
<LangVersion>11</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using PkmnLibSharp.Utils;
|
using PkmnLibSharp.Utils;
|
||||||
using Interface = PkmnLibSharp.FFI.StaticData.GrowthRate;
|
using Interface = PkmnLibSharp.FFI.StaticData.GrowthRate;
|
||||||
|
|
||||||
|
@ -22,6 +24,7 @@ namespace PkmnLibSharp.StaticData
|
||||||
|
|
||||||
public uint CalculateExperience(LevelInt level)
|
public uint CalculateExperience(LevelInt level)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(level >= 1);
|
||||||
return Interface.growth_rate_calculate_experience(Ptr, level);
|
return Interface.growth_rate_calculate_experience(Ptr, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,4 +53,120 @@ namespace PkmnLibSharp.StaticData
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of the growth rates that have been used since generation 5.
|
||||||
|
/// </summary>
|
||||||
|
public static class CommonGrowthRates
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static uint Power2(uint i)
|
||||||
|
{
|
||||||
|
return i * i;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static uint Power3(uint i)
|
||||||
|
{
|
||||||
|
return i * i * i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LookupGrowthRate Fast(LevelInt maxLevel)
|
||||||
|
{
|
||||||
|
var arr = new uint[maxLevel];
|
||||||
|
arr[0] = 0;
|
||||||
|
for (uint i = 2; i < maxLevel + 1; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = 4 * Power3(i) / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LookupGrowthRate(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LookupGrowthRate MediumFast(LevelInt maxLevel)
|
||||||
|
{
|
||||||
|
var arr = new uint[maxLevel];
|
||||||
|
arr[0] = 0;
|
||||||
|
for (uint i = 2; i < maxLevel + 1; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LookupGrowthRate(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LookupGrowthRate MediumSlow(LevelInt maxLevel)
|
||||||
|
{
|
||||||
|
var arr = new uint[maxLevel];
|
||||||
|
arr[0] = 0;
|
||||||
|
for (uint i = 2; i < maxLevel + 1; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = 6 * Power3(i) / 5 - 15 * Power2(i) + 100 * i - 140;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LookupGrowthRate(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LookupGrowthRate Slow(LevelInt maxLevel)
|
||||||
|
{
|
||||||
|
var arr = new uint[maxLevel];
|
||||||
|
arr[0] = 0;
|
||||||
|
for (uint i = 2; i < maxLevel + 1; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = 5 * Power3(i) / 4;
|
||||||
|
}
|
||||||
|
return new LookupGrowthRate(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LookupGrowthRate Erratic(LevelInt maxLevel)
|
||||||
|
{
|
||||||
|
var arr = new uint[maxLevel];
|
||||||
|
arr[0] = 0;
|
||||||
|
uint i = 2;
|
||||||
|
for (; i < 50; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (100 - i) / 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < 68; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (150 - i) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < 98; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (uint)((1911 - 10 * i) / 3.0) / 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < maxLevel + 1; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (160 - i) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LookupGrowthRate(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LookupGrowthRate Fluctuating(LevelInt maxLevel)
|
||||||
|
{
|
||||||
|
var arr = new uint[maxLevel];
|
||||||
|
arr[0] = 0;
|
||||||
|
uint i = 2;
|
||||||
|
for (; i < 15; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (uint)((Math.Floor((i + 1) / 3.0) + 24) / 50.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < 36; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (i + 14) / 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < maxLevel + 1; i++)
|
||||||
|
{
|
||||||
|
arr[i - 1] = Power3(i) * (i / 2 + 32) / 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LookupGrowthRate(arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using PkmnLibSharp.FFI;
|
using PkmnLibSharp.FFI;
|
||||||
using PkmnLibSharp.Utils;
|
using PkmnLibSharp.Utils;
|
||||||
|
@ -29,7 +30,7 @@ namespace PkmnLibSharp.StaticData.Libraries
|
||||||
return GetValueByKey(key) != null;
|
return GetValueByKey(key) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetValue(string key, out T value)
|
public bool TryGetValue(string key, [NotNullWhen(true)] out T value)
|
||||||
{
|
{
|
||||||
if (Cache.ValueCache.TryGetValue(key, out value) && value != null)
|
if (Cache.ValueCache.TryGetValue(key, out value) && value != null)
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using PkmnLibSharp.FFI;
|
using PkmnLibSharp.FFI;
|
||||||
using PkmnLibSharp.Utils;
|
using PkmnLibSharp.Utils;
|
||||||
|
@ -21,8 +22,11 @@ namespace PkmnLibSharp.StaticData.Libraries
|
||||||
Interface.growth_rate_library_calculate_level(Ptr, growthRate.ToPtr(), experience);
|
Interface.growth_rate_library_calculate_level(Ptr, growthRate.ToPtr(), experience);
|
||||||
|
|
||||||
[MustUseReturnValue]
|
[MustUseReturnValue]
|
||||||
public uint CalculateExperience(string growthRate, LevelInt level) =>
|
public uint CalculateExperience(string growthRate, LevelInt level)
|
||||||
Interface.growth_rate_library_calculate_experience(Ptr, growthRate.ToPtr(), level);
|
{
|
||||||
|
Debug.Assert(level >= 1);
|
||||||
|
return Interface.growth_rate_library_calculate_experience(Ptr, growthRate.ToPtr(), level);
|
||||||
|
}
|
||||||
|
|
||||||
public void AddGrowthRate(string name, GrowthRate growthRate) =>
|
public void AddGrowthRate(string name, GrowthRate growthRate) =>
|
||||||
Interface.growth_rate_library_add_growth_rate(Ptr, name.ToPtr(), growthRate.TakeOwnershipAndInvalidate());
|
Interface.growth_rate_library_add_growth_rate(Ptr, name.ToPtr(), growthRate.TakeOwnershipAndInvalidate());
|
||||||
|
|
|
@ -1,27 +1,49 @@
|
||||||
using System;
|
using System.Diagnostics;
|
||||||
using PkmnLibSharp.FFI;
|
using PkmnLibSharp.FFI;
|
||||||
using PkmnLibSharp.Utils;
|
using PkmnLibSharp.Utils;
|
||||||
using Interface = PkmnLibSharp.FFI.StaticData.Libraries.LibrarySettings;
|
using Interface = PkmnLibSharp.FFI.StaticData.Libraries.LibrarySettings;
|
||||||
|
|
||||||
namespace PkmnLibSharp.StaticData.Libraries
|
namespace PkmnLibSharp.StaticData.Libraries
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This library holds several misc settings for the library.
|
||||||
|
/// </summary>
|
||||||
public class LibrarySettings : ExternPointer<LibrarySettings.CacheData>
|
public class LibrarySettings : ExternPointer<LibrarySettings.CacheData>
|
||||||
{
|
{
|
||||||
public class CacheData
|
public class CacheData
|
||||||
{
|
{
|
||||||
public LevelInt? MaxLevel { get; internal set; }
|
public LevelInt? MaxLevel { get; internal set; }
|
||||||
|
public uint? ShinyRate { get; internal set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public LibrarySettings(LevelInt maxLevel) : base(Interface.library_settings_new(maxLevel), true)
|
/// <inheritdoc cref="LibrarySettings"/>
|
||||||
|
/// <param name="maxLevel">The highest level a Pokemon can be.</param>
|
||||||
|
/// <param name="shinyRate">
|
||||||
|
/// The chance of a Pokemon being shiny, as the denominator of a fraction, where the nominator
|
||||||
|
/// is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is 1/1000.
|
||||||
|
/// </param>
|
||||||
|
public LibrarySettings(LevelInt maxLevel, uint shinyRate)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(maxLevel >= 1);
|
||||||
|
Debug.Assert(shinyRate >= 1);
|
||||||
|
InitializePointer(Interface.library_settings_new(maxLevel, shinyRate), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LibrarySettings(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
|
internal LibrarySettings(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The highest level a Pokemon can be.
|
||||||
|
/// </summary>
|
||||||
public LevelInt MaxLevel => Cache.MaxLevel ??= Interface.library_settings_maximum_level(Ptr);
|
public LevelInt MaxLevel => Cache.MaxLevel ??= Interface.library_settings_maximum_level(Ptr);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The chance of a Pokemon being shiny, as the denominator of a fraction, where the nominator
|
||||||
|
/// is 1. For example, if this is 1000, then the chance of a Pokemon being shiny is 1/1000.
|
||||||
|
/// </summary>
|
||||||
|
public uint ShinyRate => Cache.ShinyRate ??= Interface.library_settings_shiny_rate(Ptr);
|
||||||
|
|
||||||
protected override CacheData CreateCache() => new();
|
protected override CacheData CreateCache() => new();
|
||||||
|
|
||||||
protected override void Destructor() => Interface.library_settings_drop(Ptr);
|
protected override void Destructor() => Interface.library_settings_drop(Ptr);
|
||||||
|
|
|
@ -34,6 +34,12 @@ namespace PkmnLibSharp.StaticData.Libraries
|
||||||
return nature;
|
return nature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Nature GetRandomNature(ulong seed)
|
||||||
|
{
|
||||||
|
return new Nature(Interface.nature_library_get_random_nature(Ptr, seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public string GetNatureName(Nature nature)
|
public string GetNatureName(Nature nature)
|
||||||
{
|
{
|
||||||
var fd = Cache.Natures.FirstOrDefault(x => x.Value == nature);
|
var fd = Cache.Natures.FirstOrDefault(x => x.Value == nature);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using PkmnLibSharp.FFI;
|
||||||
using PkmnLibSharp.Utils;
|
using PkmnLibSharp.Utils;
|
||||||
using Interface = PkmnLibSharp.FFI.StaticData.Libraries.StaticData;
|
using Interface = PkmnLibSharp.FFI.StaticData.Libraries.StaticData;
|
||||||
|
|
||||||
|
@ -18,6 +19,8 @@ namespace PkmnLibSharp.StaticData.Libraries
|
||||||
public AbilityLibrary? AbilityLibrary { get; internal set; }
|
public AbilityLibrary? AbilityLibrary { get; internal set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal StaticData(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner){}
|
||||||
|
|
||||||
public StaticData(LibrarySettings settings, SpeciesLibrary speciesLibrary, MoveLibrary moveLibrary,
|
public StaticData(LibrarySettings settings, SpeciesLibrary speciesLibrary, MoveLibrary moveLibrary,
|
||||||
ItemLibrary itemLibrary, GrowthRateLibrary growthRateLibrary, TypeLibrary typeLibrary,
|
ItemLibrary itemLibrary, GrowthRateLibrary growthRateLibrary, TypeLibrary typeLibrary,
|
||||||
NatureLibrary natureLibrary, AbilityLibrary abilityLibrary) : base(
|
NatureLibrary natureLibrary, AbilityLibrary abilityLibrary) : base(
|
||||||
|
@ -42,16 +45,16 @@ namespace PkmnLibSharp.StaticData.Libraries
|
||||||
Cache.ItemLibrary ??= new ItemLibrary(Interface.static_data_items(Ptr), false);
|
Cache.ItemLibrary ??= new ItemLibrary(Interface.static_data_items(Ptr), false);
|
||||||
|
|
||||||
public GrowthRateLibrary GrowthRateLibrary =>
|
public GrowthRateLibrary GrowthRateLibrary =>
|
||||||
Cache.GrowthRateLibrary ??= new GrowthRateLibrary(Interface.static_data_items(Ptr), false);
|
Cache.GrowthRateLibrary ??= new GrowthRateLibrary(Interface.static_data_growth_rates(Ptr), false);
|
||||||
|
|
||||||
public TypeLibrary TypeLibrary =>
|
public TypeLibrary TypeLibrary =>
|
||||||
Cache.TypeLibrary ??= new TypeLibrary(Interface.static_data_items(Ptr), false);
|
Cache.TypeLibrary ??= new TypeLibrary(Interface.static_data_types(Ptr), false);
|
||||||
|
|
||||||
public NatureLibrary NatureLibrary =>
|
public NatureLibrary NatureLibrary =>
|
||||||
Cache.NatureLibrary ??= new NatureLibrary(Interface.static_data_items(Ptr), false);
|
Cache.NatureLibrary ??= new NatureLibrary(Interface.static_data_natures(Ptr), false);
|
||||||
|
|
||||||
public AbilityLibrary AbilityLibrary =>
|
public AbilityLibrary AbilityLibrary =>
|
||||||
Cache.AbilityLibrary ??= new AbilityLibrary(Interface.static_data_items(Ptr), false);
|
Cache.AbilityLibrary ??= new AbilityLibrary(Interface.static_data_abilities(Ptr), false);
|
||||||
|
|
||||||
protected override CacheData CreateCache() => new();
|
protected override CacheData CreateCache() => new();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using PkmnLibSharp.FFI;
|
using PkmnLibSharp.FFI;
|
||||||
using PkmnLibSharp.Utils;
|
using PkmnLibSharp.Utils;
|
||||||
|
@ -38,7 +39,16 @@ namespace PkmnLibSharp.StaticData
|
||||||
public string GrowthRate => Cache.GrowthRate ??= Interface.species_growth_rate(Ptr).PtrString()!;
|
public string GrowthRate => Cache.GrowthRate ??= Interface.species_growth_rate(Ptr).PtrString()!;
|
||||||
public byte CaptureRate => Cache.CaptureRate ??= Interface.species_capture_rate(Ptr);
|
public byte CaptureRate => Cache.CaptureRate ??= Interface.species_capture_rate(Ptr);
|
||||||
|
|
||||||
public bool TryGetForm(string formName, out Form? form)
|
public Form DefaultForm
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
TryGetForm("default", out var form);
|
||||||
|
return form!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetForm(string formName, [NotNullWhen(true)] out Form? form)
|
||||||
{
|
{
|
||||||
if (Cache.Forms.TryGetValue(formName, out form))
|
if (Cache.Forms.TryGetValue(formName, out form))
|
||||||
return true;
|
return true;
|
||||||
|
@ -57,6 +67,8 @@ namespace PkmnLibSharp.StaticData
|
||||||
public void AddForm(Form form) =>
|
public void AddForm(Form form) =>
|
||||||
Interface.species_add_form(Ptr, form.Name.ToPtr(), form.TakeOwnershipAndInvalidate());
|
Interface.species_add_form(Ptr, form.Name.ToPtr(), form.TakeOwnershipAndInvalidate());
|
||||||
|
|
||||||
|
public Gender GetRandomGender(ulong seed) => Interface.species_get_random_gender(Ptr, seed);
|
||||||
|
|
||||||
protected override CacheData CreateCache() => new CacheData();
|
protected override CacheData CreateCache() => new CacheData();
|
||||||
protected override void Destructor() => Interface.species_drop(Ptr);
|
protected override void Destructor() => Interface.species_drop(Ptr);
|
||||||
|
|
||||||
|
|
|
@ -94,5 +94,40 @@ namespace PkmnLibSharp.Utils
|
||||||
_isInvalidated = true;
|
_isInvalidated = true;
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is ExternPointer<TCache> other)
|
||||||
|
{
|
||||||
|
return Identifier == other.Identifier;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool Equals(ExternPointer<TCache> other)
|
||||||
|
{
|
||||||
|
if (Identifier != 0)
|
||||||
|
{
|
||||||
|
return Identifier == other.Identifier;
|
||||||
|
}
|
||||||
|
return Ptr == other.Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
if (Identifier != 0)
|
||||||
|
return (int)Identifier;
|
||||||
|
return (int)Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(ExternPointer<TCache>? left, ExternPointer<TCache>? right)
|
||||||
|
{
|
||||||
|
return Equals(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(ExternPointer<TCache>? left, ExternPointer<TCache>? right)
|
||||||
|
{
|
||||||
|
return !Equals(left, right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace PkmnLibSharp.Utils
|
||||||
|
{
|
||||||
|
internal static class MiscExtensions
|
||||||
|
{
|
||||||
|
internal static int IndexOf<T>(this IReadOnlyList<T> list, T element)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
if (Equals(list[i], element))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,208 @@
|
||||||
|
// https://github.com/dotnet/runtime/blob/527f9ae88a0ee216b44d556f9bdc84037fe0ebda/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
|
||||||
|
|
||||||
|
#pragma warning disable
|
||||||
|
#define INTERNAL_NULLABLE_ATTRIBUTES
|
||||||
|
|
||||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
|
|
||||||
|
namespace System.Diagnostics.CodeAnalysis
|
||||||
|
{
|
||||||
|
#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
|
||||||
|
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class AllowNullAttribute : Attribute
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class DisallowNullAttribute : Attribute
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class MaybeNullAttribute : Attribute
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class NotNullAttribute : Attribute
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding type disallows it.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class MaybeNullWhenAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Initializes the attribute with the specified return value condition.</summary>
|
||||||
|
/// <param name="returnValue">
|
||||||
|
/// The return value condition. If the method returns this value, the associated parameter may be null.
|
||||||
|
/// </param>
|
||||||
|
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
|
||||||
|
|
||||||
|
/// <summary>Gets the return value condition.</summary>
|
||||||
|
public bool ReturnValue { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the corresponding type allows it.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class NotNullWhenAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Initializes the attribute with the specified return value condition.</summary>
|
||||||
|
/// <param name="returnValue">
|
||||||
|
/// The return value condition. If the method returns this value, the associated parameter will not be null.
|
||||||
|
/// </param>
|
||||||
|
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
|
||||||
|
|
||||||
|
/// <summary>Gets the return value condition.</summary>
|
||||||
|
public bool ReturnValue { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class NotNullIfNotNullAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Initializes the attribute with the associated parameter name.</summary>
|
||||||
|
/// <param name="parameterName">
|
||||||
|
/// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
|
||||||
|
/// </param>
|
||||||
|
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
|
||||||
|
|
||||||
|
/// <summary>Gets the associated parameter name.</summary>
|
||||||
|
public string ParameterName { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Applied to a method that will never return under any circumstance.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class DoesNotReturnAttribute : Attribute
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class DoesNotReturnIfAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Initializes the attribute with the specified parameter value.</summary>
|
||||||
|
/// <param name="parameterValue">
|
||||||
|
/// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
|
||||||
|
/// the associated parameter matches this value.
|
||||||
|
/// </param>
|
||||||
|
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
|
||||||
|
|
||||||
|
/// <summary>Gets the condition parameter value.</summary>
|
||||||
|
public bool ParameterValue { get; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET45 || NET451 || NET452 || NET46 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
|
||||||
|
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class MemberNotNullAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Initializes the attribute with a field or property member.</summary>
|
||||||
|
/// <param name="member">
|
||||||
|
/// The field or property member that is promised to be not-null.
|
||||||
|
/// </param>
|
||||||
|
public MemberNotNullAttribute(string member) => Members = new[] { member };
|
||||||
|
|
||||||
|
/// <summary>Initializes the attribute with the list of field and property members.</summary>
|
||||||
|
/// <param name="members">
|
||||||
|
/// The list of field and property members that are promised to be not-null.
|
||||||
|
/// </param>
|
||||||
|
public MemberNotNullAttribute(params string[] members) => Members = members;
|
||||||
|
|
||||||
|
/// <summary>Gets field or property member names.</summary>
|
||||||
|
public string[] Members { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.</summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
|
||||||
|
#if SYSTEM_PRIVATE_CORELIB
|
||||||
|
public
|
||||||
|
#else
|
||||||
|
internal
|
||||||
|
#endif
|
||||||
|
sealed class MemberNotNullWhenAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
|
||||||
|
/// <param name="returnValue">
|
||||||
|
/// The return value condition. If the method returns this value, the associated parameter will not be null.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="member">
|
||||||
|
/// The field or property member that is promised to be not-null.
|
||||||
|
/// </param>
|
||||||
|
public MemberNotNullWhenAttribute(bool returnValue, string member)
|
||||||
|
{
|
||||||
|
ReturnValue = returnValue;
|
||||||
|
Members = new[] { member };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
|
||||||
|
/// <param name="returnValue">
|
||||||
|
/// The return value condition. If the method returns this value, the associated parameter will not be null.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="members">
|
||||||
|
/// The list of field and property members that are promised to be not-null.
|
||||||
|
/// </param>
|
||||||
|
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
|
||||||
|
{
|
||||||
|
ReturnValue = returnValue;
|
||||||
|
Members = members;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Gets the return value condition.</summary>
|
||||||
|
public bool ReturnValue { get; }
|
||||||
|
|
||||||
|
/// <summary>Gets field or property member names.</summary>
|
||||||
|
public string[] Members { get; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
BIN
PkmnLibRSharp/libpkmn_lib.so (Stored with Git LFS)
BIN
PkmnLibRSharp/libpkmn_lib.so (Stored with Git LFS)
Binary file not shown.
|
@ -0,0 +1,130 @@
|
||||||
|
using System;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using PkmnLibSharp.DynamicData;
|
||||||
|
using PkmnLibSharp.DynamicData.Libraries;
|
||||||
|
using PkmnLibSharp.StaticData;
|
||||||
|
using PkmnLibSharp.StaticData.Libraries;
|
||||||
|
|
||||||
|
namespace PkmnLibRSharpTests.DynamicData
|
||||||
|
{
|
||||||
|
public class PokemonTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetLibrary()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(library, pokemon.Library);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetSpecies()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(library.StaticData.SpeciesLibrary["testSpecies"], pokemon.Species);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetForm()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(library.StaticData.SpeciesLibrary["testSpecies"].DefaultForm, pokemon.Form);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetDisplaySpecies()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(library.StaticData.SpeciesLibrary["testSpecies"], pokemon.Species);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetDisplayForm()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(library.StaticData.SpeciesLibrary["testSpecies"].DefaultForm, pokemon.Form);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetLevel()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(100, pokemon.Level);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetExperience()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).Build();
|
||||||
|
Assert.AreEqual(library.StaticData.GrowthRateLibrary.CalculateExperience("testGrowthrate", 100),
|
||||||
|
pokemon.Experience);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetUniqueIdentifier()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).WithIdentifier(1000).Build();
|
||||||
|
Assert.AreEqual(1000, pokemon.UniqueIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetGender()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).WithGender(Gender.Male).Build();
|
||||||
|
Assert.AreEqual(Gender.Male, pokemon.Gender);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Pokemon_GetColoring()
|
||||||
|
{
|
||||||
|
using var library = GetLibrary();
|
||||||
|
using var pokemon = new PokemonBuilder(library, "testSpecies", 100).ForceShiny(true).Build();
|
||||||
|
Assert.AreEqual(1, pokemon.Coloring);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DynamicLibrary GetLibrary()
|
||||||
|
{
|
||||||
|
using var settings = new LibrarySettings(100, 4096);
|
||||||
|
using var speciesLibrary = new SpeciesLibrary(0);
|
||||||
|
FillSpeciesLibrary(speciesLibrary);
|
||||||
|
using var moves = new MoveLibrary(0);
|
||||||
|
using var items = new ItemLibrary(0);
|
||||||
|
using var growthRates = new GrowthRateLibrary(0);
|
||||||
|
using var gr = CommonGrowthRates.Erratic(100);
|
||||||
|
growthRates.AddGrowthRate("testGrowthrate", gr);
|
||||||
|
using var types = new TypeLibrary(0);
|
||||||
|
using var natures = new NatureLibrary(0);
|
||||||
|
natures.LoadNature("testNature", Nature.NeutralNature());
|
||||||
|
using var abilities = new AbilityLibrary(0);
|
||||||
|
using var library = new PkmnLibSharp.StaticData.Libraries.StaticData(settings, speciesLibrary, moves, items,
|
||||||
|
growthRates, types, natures, abilities);
|
||||||
|
|
||||||
|
using var statCalc = new Gen7BattleStatCalculator();
|
||||||
|
using var damageLib = new Gen7DamageLibrary(false);
|
||||||
|
using var miscLib = new Gen7MiscLibrary();
|
||||||
|
using var scriptResolver = new WasmScriptResolver();
|
||||||
|
|
||||||
|
return new DynamicLibrary(library, statCalc, damageLib, miscLib, scriptResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FillSpeciesLibrary(SpeciesLibrary speciesLibrary)
|
||||||
|
{
|
||||||
|
using var stats = new StaticStatisticSet<short>(5, 10, 30, 20, 2, 0);
|
||||||
|
using var moves = new LearnableMoves();
|
||||||
|
using var form = new Form("foobar", 0.2f, 5.8f, 300, new TypeIdentifier[] { new(1), new(2) }, stats,
|
||||||
|
new[] { "foo", "bar" }, new[] { "set" }, moves, Array.Empty<string>());
|
||||||
|
using var species =
|
||||||
|
new Species(10, "testSpecies", 0.2f, "testGrowthrate", 120, form, Array.Empty<string>());
|
||||||
|
speciesLibrary.Add(species.Name, species);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using PkmnLibSharp.StaticData;
|
||||||
|
|
||||||
|
namespace PkmnLibRSharpTests.StaticData.Libraries
|
||||||
|
{
|
||||||
|
public class CommonGrowthRateTests
|
||||||
|
{
|
||||||
|
[TestCase(1, 0)]
|
||||||
|
[TestCase(20, 12_800)]
|
||||||
|
[TestCase(40, 76_800)]
|
||||||
|
[TestCase(60, 194_400)]
|
||||||
|
[TestCase(68, 257_834)]
|
||||||
|
[TestCase(70, 276_458)]
|
||||||
|
[TestCase(80, 378_880)]
|
||||||
|
[TestCase(90, 491_346)]
|
||||||
|
[TestCase(98, 583_539)]
|
||||||
|
[TestCase(100, 600_000)]
|
||||||
|
public void ErraticExperience(byte level, int experience)
|
||||||
|
{
|
||||||
|
using var growthRate = CommonGrowthRates.Erratic(100);
|
||||||
|
Assert.AreEqual(experience, growthRate.CalculateExperience(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1, 0)]
|
||||||
|
[TestCase(20, 6_400)]
|
||||||
|
[TestCase(40, 51_200)]
|
||||||
|
[TestCase(60, 172_800)]
|
||||||
|
[TestCase(70, 274_400)]
|
||||||
|
[TestCase(80, 409_600)]
|
||||||
|
[TestCase(90, 583_200)]
|
||||||
|
[TestCase(100, 800_000)]
|
||||||
|
public void FastExperience(byte level, int experience)
|
||||||
|
{
|
||||||
|
using var growthRate = CommonGrowthRates.Fast(100);
|
||||||
|
Assert.AreEqual(experience, growthRate.CalculateExperience(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1, 0)]
|
||||||
|
[TestCase(20, 8_000)]
|
||||||
|
[TestCase(40, 64_000)]
|
||||||
|
[TestCase(60, 216_000)]
|
||||||
|
[TestCase(70, 343_000)]
|
||||||
|
[TestCase(80, 512_000)]
|
||||||
|
[TestCase(90, 729_000)]
|
||||||
|
[TestCase(100, 1_000_000)]
|
||||||
|
public void MediumFastExperience(byte level, int experience)
|
||||||
|
{
|
||||||
|
using var growthRate = CommonGrowthRates.MediumFast(100);
|
||||||
|
Assert.AreEqual(experience, growthRate.CalculateExperience(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1, 0)]
|
||||||
|
[TestCase(20, 5_460)]
|
||||||
|
[TestCase(40, 56_660)]
|
||||||
|
[TestCase(60, 211_060)]
|
||||||
|
[TestCase(70, 344_960)]
|
||||||
|
[TestCase(80, 526_260)]
|
||||||
|
[TestCase(90, 762_160)]
|
||||||
|
[TestCase(100, 1_059_860)]
|
||||||
|
public void MediumSlowExperience(byte level, int experience)
|
||||||
|
{
|
||||||
|
using var growthRate = CommonGrowthRates.MediumSlow(100);
|
||||||
|
Assert.AreEqual(experience, growthRate.CalculateExperience(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1, 0)]
|
||||||
|
[TestCase(20, 10_000)]
|
||||||
|
[TestCase(40, 80_000)]
|
||||||
|
[TestCase(60, 270_000)]
|
||||||
|
[TestCase(70, 428_750)]
|
||||||
|
[TestCase(80, 640_000)]
|
||||||
|
[TestCase(90, 911_250)]
|
||||||
|
[TestCase(100, 1_250_000)]
|
||||||
|
public void SlowExperience(byte level, int experience)
|
||||||
|
{
|
||||||
|
using var growthRate = CommonGrowthRates.Slow(100);
|
||||||
|
Assert.AreEqual(experience, growthRate.CalculateExperience(level));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1, 0)]
|
||||||
|
[TestCase(20, 5_440)]
|
||||||
|
[TestCase(40, 66_560)]
|
||||||
|
[TestCase(60, 267_840)]
|
||||||
|
[TestCase(70, 459_620)]
|
||||||
|
[TestCase(80, 737_280)]
|
||||||
|
[TestCase(90, 1_122_660)]
|
||||||
|
[TestCase(100, 1_640_000)]
|
||||||
|
public void FluctuatingExperience(byte level, int experience)
|
||||||
|
{
|
||||||
|
using var growthRate = CommonGrowthRates.Fluctuating(100);
|
||||||
|
Assert.AreEqual(experience, growthRate.CalculateExperience(level));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,13 +8,13 @@ namespace PkmnLibRSharpTests.StaticData.Libraries
|
||||||
[Test]
|
[Test]
|
||||||
public void CreateLibrarySettings()
|
public void CreateLibrarySettings()
|
||||||
{
|
{
|
||||||
using var settings = new LibrarySettings(100);
|
using var settings = new LibrarySettings(100, 4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void GetMaxLevel()
|
public void GetMaxLevel()
|
||||||
{
|
{
|
||||||
using var settings = new LibrarySettings(100);
|
using var settings = new LibrarySettings(100, 4096);
|
||||||
Assert.AreEqual(100, settings.MaxLevel);
|
Assert.AreEqual(100, settings.MaxLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace PkmnLibRSharpTests.StaticData.Libraries
|
||||||
{
|
{
|
||||||
private PkmnLibSharp.StaticData.Libraries.StaticData Build()
|
private PkmnLibSharp.StaticData.Libraries.StaticData Build()
|
||||||
{
|
{
|
||||||
using var settings = new LibrarySettings(100);
|
using var settings = new LibrarySettings(100, 4096);
|
||||||
using var species = new SpeciesLibrary(0);
|
using var species = new SpeciesLibrary(0);
|
||||||
using var moves = new MoveLibrary(0);
|
using var moves = new MoveLibrary(0);
|
||||||
using var items = new ItemLibrary(0);
|
using var items = new ItemLibrary(0);
|
||||||
|
|
Loading…
Reference in New Issue