Initial work on battle side.

This commit is contained in:
Deukhoofd 2020-07-18 16:49:11 +02:00
parent 5ad3e2e040
commit 049eb480c0
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
39 changed files with 835 additions and 88 deletions

View File

@ -0,0 +1,31 @@
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class AngelScriptResolver : ScriptResolver
{
public AngelScriptResolver() : base(Pkmnlib.Generated.AngelScriptResolver.Construct())
{
}
public void Initialize(BattleLibrary library)
{
Pkmnlib.Generated.AngelScriptResolver.Initialize(Ptr, library.Ptr).Assert();
}
public void CreateScript(string name, string script)
{
Pkmnlib.Generated.AngelScriptResolver.CreateScript(Ptr, name.ToPtr(), script.ToPtr()).Assert();
}
public void FinalizeModule()
{
Pkmnlib.Generated.AngelScriptResolver.FinalizeModule(Ptr).Assert();
}
protected override void DeletePtr()
{
Pkmnlib.Generated.AngelScriptResolver.Destruct(Ptr).Assert();
}
}
}

View File

@ -0,0 +1,99 @@
using System;
using PkmnLibSharp.Library;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class BattleLibrary : PointerWrapper
{
private PokemonLibrary _static;
private StatCalculator _statCalculator;
private DamageLibrary _damageLibrary;
private MiscLibrary _miscLibrary;
private ExperienceLibrary _experienceLibrary;
public PokemonLibrary StaticLibrary
{
get
{
if (_static != null) return _static;
var ptr = Creaturelibbattling.Generated.BattleLibrary.GetStaticLib(Ptr);
if (TryResolvePointer(ptr, out _static))
return _static;
_static = new PokemonLibrary(ptr);
return _static;
}
}
public StatCalculator StatCalculator
{
get
{
if (_statCalculator != null) return _statCalculator;
var ptr = Creaturelibbattling.Generated.BattleLibrary.GetStatCalculator(Ptr);
if (TryResolvePointer(ptr, out _statCalculator))
return _statCalculator;
_statCalculator = new StatCalculator(ptr);
return _statCalculator;
}
}
public DamageLibrary DamageLibrary
{
get
{
if (_damageLibrary != null) return _damageLibrary;
var ptr = Creaturelibbattling.Generated.BattleLibrary.GetDamageLibrary(Ptr);
if (TryResolvePointer(ptr, out _damageLibrary))
return _damageLibrary;
_damageLibrary = new DamageLibrary(ptr);
return _damageLibrary;
}
}
public MiscLibrary MiscLibrary
{
get
{
if (_miscLibrary != null) return _miscLibrary;
var ptr = Creaturelibbattling.Generated.BattleLibrary.GetMiscLibrary(Ptr);
if (TryResolvePointer(ptr, out _miscLibrary))
return _miscLibrary;
_miscLibrary = new MiscLibrary(ptr);
return _miscLibrary;
}
}
public ExperienceLibrary ExperienceLibrary
{
get
{
if (_experienceLibrary != null) return _experienceLibrary;
var ptr = Creaturelibbattling.Generated.BattleLibrary.GetExperienceLibrary(Ptr);
if (TryResolvePointer(ptr, out _experienceLibrary))
return _experienceLibrary;
_experienceLibrary = new ExperienceLibrary(ptr);
return _experienceLibrary;
}
}
private BattleLibrary(IntPtr ptr) : base(ptr)
{
}
public static BattleLibrary Create(PokemonLibrary staticLibrary, StatCalculator statCalculator,
DamageLibrary damageLibrary, ExperienceLibrary experienceLibrary, ScriptResolver scriptResolver,
MiscLibrary miscLibrary)
{
var ptr = IntPtr.Zero;
Pkmnlib.Generated.BattleLibrary.Construct(ref ptr, staticLibrary.Ptr, statCalculator.Ptr, damageLibrary.Ptr,
experienceLibrary.Ptr, scriptResolver.Ptr, miscLibrary.Ptr).Assert();
return new BattleLibrary(ptr);
}
protected override void DeletePtr()
{
Pkmnlib.Generated.BattleLibrary.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class DamageLibrary : PointerWrapper
{
internal DamageLibrary(IntPtr ptr) : base(ptr)
{
}
public DamageLibrary() : base(Pkmnlib.Generated.DamageLibrary.Construct())
{
}
public uint GetDamage(IntPtr attack, Pokemon target, byte hitIndex, IntPtr hitData)
{
uint val = 0;
Creaturelibbattling.Generated.DamageLibrary.GetDamage(ref val, Ptr, attack, target.Ptr, hitIndex, hitData)
.Assert();
return val;
}
public byte GetBasePower(IntPtr attack, Pokemon target, byte hitIndex, IntPtr hitData)
{
byte val = 0;
Creaturelibbattling.Generated.DamageLibrary.GetBasePower(ref val, Ptr, attack, target.Ptr, hitIndex, hitData)
.Assert();
return val;
}
public float GetStatModifier(IntPtr attack, Pokemon target, byte hitIndex, IntPtr hitData)
{
float val = 0;
Creaturelibbattling.Generated.DamageLibrary.GetStatModifier(ref val, Ptr, attack, target.Ptr, hitIndex, hitData)
.Assert();
return val;
}
public float GetDamageModifier(IntPtr attack, Pokemon target, byte hitIndex, IntPtr hitData)
{
float val = 0;
Creaturelibbattling.Generated.DamageLibrary
.GetDamageModifier(ref val, Ptr, attack, target.Ptr, hitIndex, hitData)
.Assert();
return val;
}
protected override void DeletePtr()
{
Pkmnlib.Generated.DamageLibrary.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class ExperienceLibrary : PointerWrapper
{
public ExperienceLibrary(IntPtr ptr) : base(ptr)
{
}
public ExperienceLibrary() : base(Pkmnlib.Generated.ExperienceLibrary.Construct())
{
}
void HandleExperienceGain(Pokemon faintedMon, IReadOnlyCollection<Pokemon> opponents)
{
Pkmnlib.Generated.ExperienceLibrary.HandleExperienceGain(Ptr, faintedMon.Ptr,
opponents.Select(x => x.Ptr).ToArray().ArrayPtr(),
(ulong) opponents.Count);
}
protected override void DeletePtr()
{
Pkmnlib.Generated.ExperienceLibrary.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,7 @@
namespace PkmnLibSharp.Battling
{
public enum Gender
{
Male, Female, Genderless
}
}

View File

@ -0,0 +1,25 @@
using System;
using Creaturelibbattling;
using Creaturelibbattling.Generated;
using PkmnLibSharp.Library.Moves;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class LearnedMove : PointerWrapper
{
internal LearnedMove(IntPtr ptr) : base(ptr){}
public static LearnedMove Create(MoveData move, byte maxUses, MoveLearnMethod learnMethod)
{
var ptr = IntPtr.Zero;
LearnedAttack.Construct(ref ptr, move.Ptr, maxUses, (AttackLearnMethod) learnMethod).Assert();
return new LearnedMove(ptr);
}
protected override void DeletePtr()
{
LearnedAttack.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,43 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class MiscLibrary : PointerWrapper
{
internal MiscLibrary(IntPtr ptr) : base(ptr)
{
}
public MiscLibrary() : base(Pkmnlib.Generated.MiscLibrary.Construct())
{
}
public bool IsCritical(IntPtr move, Pokemon target, byte hitNumber)
{
byte b = 0;
Creaturelibbattling.Generated.MiscLibrary.IsCritical(ref b, Ptr, move, target.Ptr, hitNumber).Assert();
return b == MarshalHelper.True;
}
public bool CanFlee(IntPtr switchChoice)
{
byte b = 0;
Creaturelibbattling.Generated.MiscLibrary.CanFlee(ref b, Ptr, switchChoice).Assert();
return b == MarshalHelper.True;
}
public IntPtr ReplacementAttack(Pokemon user, byte sideTarget, byte creatureTarget)
{
var b = IntPtr.Zero;
Creaturelibbattling.Generated.MiscLibrary.ReplacementAttack(ref b, Ptr, user.Ptr, sideTarget, creatureTarget)
.Assert();
return b;
}
protected override void DeletePtr()
{
Pkmnlib.Generated.MiscLibrary.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,8 @@
namespace PkmnLibSharp.Battling
{
public enum MoveLearnMethod
{
Unknown = 0,
Level = 1,
}
}

View File

@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Linq;
using PkmnLibSharp.Library;
using PkmnLibSharp.Utilities;
using Item = PkmnLibSharp.Library.Items.Item;
using Nature = PkmnLibSharp.Library.Nature;
namespace PkmnLibSharp.Battling
{
public class Pokemon : PointerWrapper
{
public Pokemon(BattleLibrary library, Species species, Forme forme, byte level, uint experience, uint uid,
Gender gender, byte coloring, Item heldItem, string nickname, bool hiddenAbility, byte abilityIndex,
IReadOnlyCollection<LearnedMove> moves, StatisticSet<byte> ivs, StatisticSet<byte> evs, Nature nature) :
base(Pkmnlib.Generated.Pokemon.Construct(library.Ptr, species.Ptr, forme.Ptr, level, experience,
uid, (Pkmnlib.Gender) gender, coloring, heldItem.Ptr, nickname.ToPtr(), hiddenAbility.ToNative(),
abilityIndex,
moves.Select(x => x.Ptr).ToArray().ArrayPtr(),
(ulong) moves.Count,
ivs.HP, ivs.Attack, ivs.Defense, ivs.SpecialAttack,
ivs.SpecialDefense, ivs.Speed, evs.HP, evs.Attack, evs.Defense,
evs.SpecialAttack, evs.SpecialDefense, evs.Speed, nature.Ptr))
{}
protected override void DeletePtr()
{
Pkmnlib.Generated.Pokemon.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using PkmnLibSharp.Library;
using PkmnLibSharp.Library.Items;
using Random = PkmnLibSharp.Utilities.Random;
namespace PkmnLibSharp.Battling
{
public class PokemonBuilder
{
private BattleLibrary _library;
public string Species { get; }
public string Forme { get; private set; } = "default";
public string Nickname { get; private set; } = "";
public string Ability { get; private set; } = "";
public string Nature { get; private set; } = "";
public Gender Gender { get; private set; } = (Gender) (-1);
public uint Identifier { get; private set; } = 0;
public byte Level { get; }
public StatisticSet<byte> IVs;
public StatisticSet<byte> EVs;
public bool? IsForceShiny { get; private set; }
public string HeldItem { get; private set; }
public List<(string moveName, MoveLearnMethod learnMethod)> LearnedMoves { get; } =
new List<(string moveName, MoveLearnMethod learnMethod)>();
public PokemonBuilder(BattleLibrary library, string species, byte level)
{
_library = library;
Species = species;
Level = level;
}
public PokemonBuilder WithForme(string forme)
{
Forme = forme;
return this;
}
public PokemonBuilder WithGender(Gender gender)
{
Gender = gender;
return this;
}
public PokemonBuilder ForceShiny(bool value)
{
IsForceShiny = value;
return this;
}
public PokemonBuilder WithHeldItem(string heldItem)
{
HeldItem = heldItem;
return this;
}
public PokemonBuilder LearnMove(string moveName, MoveLearnMethod moveLearnMethod)
{
if (LearnedMoves.Count > _library.StaticLibrary.Settings.MaximalMoves)
{
throw new Exception("Too many moves for Pokemon.");
}
LearnedMoves.Add((moveName, moveLearnMethod));
return this;
}
public Pokemon Build()
{
if (!_library.StaticLibrary.SpeciesLibrary.TryGet(Species, out var species))
{
throw new Exception($"Species '{Species}' was not found.");
}
if (!species.TryGetForme(Forme, out var forme))
{
throw new Exception($"Forme '{Forme}' was not found on species '{Species}'");
}
var experience = _library.StaticLibrary.GrowthRateLibrary.CalculateExperience(species.GrowthRate, Level);
var random = new Random();
var uid = random.GetUnsigned(0, uint.MaxValue);
if (Gender == (Gender) (-1))
{
Gender = species.GetRandomGender(random);
}
byte coloring = 0;
if (IsForceShiny.HasValue)
{
coloring = (byte) (IsForceShiny.Value ? 1 : 0);
}
else if (random.Get(_library.StaticLibrary.Settings.ShinyRate) == 0)
{
coloring = 1;
}
Item heldItem = null;
if (HeldItem != null)
{
if (!_library.StaticLibrary.ItemLibrary.TryGet(HeldItem, out heldItem))
{
throw new Exception($"Item '{HeldItem}' was not found.");
}
}
byte abilityIndex = 0;
var isHiddenAbility = false;
if (string.IsNullOrEmpty(Ability))
{
abilityIndex = forme.GetRandomAbility(random);
}
else
{
abilityIndex = (byte) forme.Abilities.IndexOf(Ability);
if (abilityIndex == -1)
{
abilityIndex = (byte) forme.HiddenAbilities.IndexOf(Ability);
if (abilityIndex == -1)
{
throw new Exception(
$"Invalid ability '{Ability}' for Pokemon '{species.Name}' and forme '{forme.Name}'.");
}
isHiddenAbility = true;
}
}
var moves = new LearnedMove[_library.StaticLibrary.Settings.MaximalMoves];
for (var i = 0; i < LearnedMoves.Count; i++)
{
if (!_library.StaticLibrary.MoveLibrary.TryGet(LearnedMoves[i].moveName, out var move))
{
throw new Exception($"Move '{LearnedMoves[i].moveName}' was not found.");
}
moves[i] = LearnedMove.Create(move, move.BaseUsages, LearnedMoves[i].learnMethod);
}
if (string.IsNullOrEmpty(Nature))
{
Nature = _library.StaticLibrary.NatureLibrary.GetRandomNatureName(random);
}
var nature = _library.StaticLibrary.NatureLibrary.GetNature(Nature);
return new Pokemon(_library, species, forme, Level, experience, uid, Gender, coloring, heldItem, Nickname,
isHiddenAbility, abilityIndex, moves, IVs, EVs, nature);
}
}
}

View File

@ -0,0 +1,12 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public abstract class ScriptResolver : PointerWrapper
{
protected ScriptResolver(IntPtr ptr) : base(ptr)
{
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using PkmnLibSharp.Library;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Battling
{
public class StatCalculator : PointerWrapper
{
internal StatCalculator(IntPtr ptr) : base(ptr)
{
}
public StatCalculator() : base(Pkmnlib.Generated.StatCalculator.Construct())
{
}
public uint CalculateFlatStat(Pokemon pokemon, Statistic stat)
{
uint val = 0;
Creaturelibbattling.Generated.BattleStatCalculator
.CalculateFlatStat(ref val, Ptr, pokemon.Ptr, (Creaturelibbattling.Statistic) stat).Assert();
return val;
}
public uint CalculateBoostedStat(Pokemon pokemon, Statistic stat)
{
uint val = 0;
Creaturelibbattling.Generated.BattleStatCalculator
.CalculateBoostedStat(ref val, Ptr, pokemon.Ptr, (Creaturelibbattling.Statistic) stat).Assert();
return val;
}
protected override void DeletePtr()
{
Pkmnlib.Generated.StatCalculator.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1,75 @@
// AUTOMATICALLY GENERATED, DO NOT EDIT
using System;
using System.Runtime.InteropServices;
namespace Arbutils.Generated
{
internal static class Random
{
/// <returns>Random *</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_Construct")]
internal static extern IntPtr Construct();
/// <param name="seed">long unsigned int</param>
/// <returns>Random *</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_ConstructWithSeed")]
internal static extern IntPtr ConstructWithSeed(ulong seed);
/// <param name="p">Random *</param>
/// <returns>void</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_Destruct")]
internal static extern void Destruct(IntPtr p);
/// <param name="p">Random *</param>
/// <returns>float</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetFloat")]
internal static extern float GetFloat(IntPtr p);
/// <param name="p">Random *</param>
/// <returns>double</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetDouble")]
internal static extern double GetDouble(IntPtr p);
/// <param name="p">Random *</param>
/// <returns>int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_Get")]
internal static extern int Get(IntPtr p);
/// <param name="p">Random *</param>
/// <param name="max">int</param>
/// <returns>int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetWithMax")]
internal static extern int GetWithMax(IntPtr p, int max);
/// <param name="p">Random *</param>
/// <param name="min">int</param>
/// <param name="max">int</param>
/// <returns>int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetInLimits")]
internal static extern int GetInLimits(IntPtr p, int min, int max);
/// <param name="p">Random *</param>
/// <returns>unsigned int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetUnsigned")]
internal static extern uint GetUnsigned(IntPtr p);
/// <param name="p">Random *</param>
/// <param name="max">unsigned int</param>
/// <returns>unsigned int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetUnsignedWithMax")]
internal static extern uint GetUnsignedWithMax(IntPtr p, uint max);
/// <param name="p">Random *</param>
/// <param name="min">unsigned int</param>
/// <param name="max">unsigned int</param>
/// <returns>unsigned int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetUnsignedInLimits")]
internal static extern uint GetUnsignedInLimits(IntPtr p, uint min, uint max);
/// <param name="p">Random *</param>
/// <returns>long unsigned int</returns>
[DllImport("Arbutils", CallingConvention = CallingConvention.Cdecl, EntryPoint= "Arbutils_Random_GetSeed")]
internal static extern ulong GetSeed(IntPtr p);
}
}

View File

@ -211,10 +211,9 @@ namespace Creaturelibbattling.Generated
internal static extern ulong GetAttacksCount(IntPtr p);
/// <param name="p">Creature *</param>
/// <param name="index">long unsigned int</param>
/// <returns>const LearnedAttack * *</returns>
[DllImport("CreatureLibBattling", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Creature_GetAttack")]
internal static extern IntPtr GetAttack(IntPtr p, ulong index);
[DllImport("CreatureLibBattling", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_Creature_GetAttacks")]
internal static extern IntPtr GetAttacks(IntPtr p);
/// <param name="p">const Creature *</param>
/// <returns>const CreatureSpecies *</returns>

View File

@ -80,12 +80,12 @@ namespace Creatureliblibrary.Generated
[DllImport("CreatureLibLibrary", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_CreatureSpecies_GetVariant")]
internal static extern byte GetVariant(ref IntPtr @out, IntPtr p, IntPtr name);
/// <param name="out">const SpeciesVariant *</param>
/// <param name="out">const SpeciesVariant * &</param>
/// <param name="p">const CreatureSpecies *</param>
/// <param name="hash">unsigned int</param>
/// <returns>unsigned char</returns>
[DllImport("CreatureLibLibrary", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_CreatureSpecies_GetVariantWithHash")]
internal static extern byte GetVariantWithHash(IntPtr @out, IntPtr p, uint hash);
internal static extern byte GetVariantWithHash(ref IntPtr @out, IntPtr p, uint hash);
/// <param name="p">CreatureSpecies *</param>
/// <param name="name">const char *</param>
@ -94,5 +94,11 @@ namespace Creatureliblibrary.Generated
[DllImport("CreatureLibLibrary", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_CreatureSpecies_SetVariant")]
internal static extern byte SetVariant(IntPtr p, IntPtr name, IntPtr variant);
/// <param name="p">CreatureSpecies *</param>
/// <param name="random">Random *</param>
/// <returns>Gender</returns>
[DllImport("CreatureLibLibrary", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_CreatureSpecies_GetRandomGender")]
internal static extern Gender GetRandomGender(IntPtr p, IntPtr random);
}
}

View File

@ -92,5 +92,11 @@ namespace Creatureliblibrary.Generated
[DllImport("CreatureLibLibrary", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_SpeciesVariant_GetLearnableAttacks")]
internal static extern IntPtr GetLearnableAttacks(IntPtr p);
/// <param name="p">SpeciesVariant *</param>
/// <param name="rand">Random *</param>
/// <returns>unsigned char</returns>
[DllImport("CreatureLibLibrary", CallingConvention = CallingConvention.Cdecl, EntryPoint= "CreatureLib_SpeciesVariant_GetRandomTalent")]
internal static extern byte GetRandomTalent(IntPtr p, IntPtr rand);
}
}

View File

@ -0,0 +1,27 @@
// AUTOMATICALLY GENERATED, DO NOT EDIT
using System;
using System.Runtime.InteropServices;
namespace Pkmnlib.Generated
{
internal static class ExperienceLibrary
{
/// <returns>ExperienceLibrary *</returns>
[DllImport("pkmnLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "PkmnLib_ExperienceLibrary_Construct")]
internal static extern IntPtr Construct();
/// <param name="p">ExperienceLibrary *</param>
/// <param name="faintedMon">Creature *</param>
/// <param name="opponents">const Creature * *</param>
/// <param name="numberOfOpponents">long unsigned int</param>
/// <returns>unsigned char</returns>
[DllImport("pkmnLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "PkmnLib_ExperienceLibrary_HandleExperienceGain")]
internal static extern byte HandleExperienceGain(IntPtr p, IntPtr faintedMon, IntPtr opponents, ulong numberOfOpponents);
/// <param name="p">ExperienceLibrary *</param>
/// <returns>void</returns>
[DllImport("pkmnLib", CallingConvention = CallingConvention.Cdecl, EntryPoint= "PkmnLib_ExperienceLibrary_Destruct")]
internal static extern void Destruct(IntPtr p);
}
}

View File

@ -2,19 +2,23 @@ using System;
using System.Collections.Immutable;
using System.Linq;
using System.Runtime.InteropServices;
using Creatureliblibrary;
using Creatureliblibrary.Generated;
using PkmnLibSharp.Utilities;
using Random = PkmnLibSharp.Utilities.Random;
namespace PkmnLibSharp.Library
{
public class Forme : PointerWrapper
{
private string _name;
private ImmutableArray<byte> _types;
private ImmutableArray<string> _abilities;
private ImmutableArray<string> _hiddenAbilities;
private LearnableMoves _moves;
private string _name;
private ImmutableArray<byte> _types;
internal Forme(IntPtr parent) : base(parent)
{
}
public string Name => _name ??= SpeciesVariant.GetName(Ptr).PtrString();
public float Height => SpeciesVariant.GetHeight(Ptr);
@ -30,10 +34,7 @@ namespace PkmnLibSharp.Library
var typesCount = SpeciesVariant.GetTypeCount(Ptr);
var types = new byte[typesCount];
for (ulong i = 0; i < typesCount; i++)
{
types[i] = SpeciesVariant.GetType(Ptr, i);
}
for (ulong i = 0; i < typesCount; i++) types[i] = SpeciesVariant.GetType(Ptr, i);
_types = types.ToImmutableArray();
return _types;
@ -63,7 +64,7 @@ namespace PkmnLibSharp.Library
var abilities = new string[abilityCount];
for (byte i = 0; i < abilityCount; i++)
{
IntPtr s = IntPtr.Zero;
var s = IntPtr.Zero;
SpeciesVariant.GetTalent(Ptr, MarshalHelper.False, i, ref s).Assert();
abilities[i] = s.PtrString();
}
@ -84,7 +85,7 @@ namespace PkmnLibSharp.Library
var abilities = new string[abilityCount];
for (byte i = 0; i < abilityCount; i++)
{
IntPtr s = IntPtr.Zero;
var s = IntPtr.Zero;
SpeciesVariant.GetTalent(Ptr, MarshalHelper.True, i, ref s).Assert();
abilities[i] = s.PtrString();
}
@ -100,10 +101,7 @@ namespace PkmnLibSharp.Library
{
if (_moves != null) return _moves;
var movesPtr = SpeciesVariant.GetLearnableAttacks(Ptr);
if (!TryResolvePointer(movesPtr, out _moves))
{
_moves = new LearnableMoves(movesPtr);
}
if (!TryResolvePointer(movesPtr, out _moves)) _moves = new LearnableMoves(movesPtr);
return _moves;
}
@ -114,33 +112,30 @@ namespace PkmnLibSharp.Library
return Types[index];
}
public static unsafe Forme Create(string name, float height, float weight, uint baseExperience, byte[] types,
public static Forme Create(string name, float height, float weight, uint baseExperience, byte[] types,
ushort baseHealth, ushort baseAttack, ushort baseDefense, ushort baseSpecialAttack,
ushort baseSpecialDefense, ushort baseSpeed, string[] abilities, string[] hiddenAbilities,
LearnableMoves moves)
{
var abilitiesConverted = abilities.Select(x => x.ToPtr()).ToArray();
var hiddenAbilitiesConverted = hiddenAbilities.Select(x => x.ToPtr()).ToArray();
fixed (IntPtr* ab = abilitiesConverted)
{
fixed (IntPtr* hab = hiddenAbilitiesConverted)
{
var ptr = SpeciesVariant.Construct(name.ToPtr(), height, weight, baseExperience, types.ArrayPtr(),
(ulong) types.Length, baseHealth, baseAttack, baseDefense, baseSpecialAttack,
baseSpecialDefense, baseSpeed, (IntPtr) ab, (ulong) abilities.Length, (IntPtr) hab,
(ulong) hiddenAbilities.Length, moves.Ptr);
var f = new Forme(ptr);
foreach (var intPtr in abilitiesConverted)
Marshal.FreeHGlobal(intPtr);
foreach (var intPtr in hiddenAbilitiesConverted)
Marshal.FreeHGlobal(intPtr);
return f;
}
}
var ab = abilitiesConverted.ArrayPtr();
var hab = abilitiesConverted.ArrayPtr();
var ptr = SpeciesVariant.Construct(name.ToPtr(), height, weight, baseExperience, types.ArrayPtr(),
(ulong) types.Length, baseHealth, baseAttack, baseDefense, baseSpecialAttack,
baseSpecialDefense, baseSpeed, (IntPtr) ab, (ulong) abilities.Length, (IntPtr) hab,
(ulong) hiddenAbilities.Length, moves.Ptr);
var f = new Forme(ptr);
foreach (var intPtr in abilitiesConverted)
Marshal.FreeHGlobal(intPtr);
foreach (var intPtr in hiddenAbilitiesConverted)
Marshal.FreeHGlobal(intPtr);
return f;
}
internal Forme(IntPtr parent) : base(parent)
public byte GetRandomAbility(Random rand)
{
return SpeciesVariant.GetRandomTalent(Ptr, rand.Ptr);
}
protected internal override void MarkAsDeleted()

View File

@ -6,6 +6,6 @@ namespace PkmnLibSharp.Library.Items
Healing = 1,
StatusHealing = 2,
Pokeball = 3,
MiscBattleItem = 4,
MiscBattleItem = 4
}
}

View File

@ -8,6 +8,10 @@ namespace PkmnLibSharp.Library.Items
{
private string _name;
internal Item(IntPtr ptr) : base(ptr)
{
}
public string Name => _name ??= Creatureliblibrary.Generated.Item.GetName(Ptr).PtrString();
public ItemCategory Category => (ItemCategory) Creatureliblibrary.Generated.Item.GetCategory(Ptr);
@ -22,10 +26,6 @@ namespace PkmnLibSharp.Library.Items
return Creatureliblibrary.Generated.Item.HasFlag(Ptr, s.ToPtr()) == MarshalHelper.True;
}
internal Item(IntPtr ptr) : base(ptr)
{
}
public static Item Create(string name, ItemCategory category, BattleItemCategory battleCategory,
int price,
string[] flags, byte flingPower)

View File

@ -9,6 +9,6 @@ namespace PkmnLibSharp.Library
TechnicalMachine = 4,
FormeChanger = 5,
KeyItem = 6,
Mail = 7,
Mail = 7
}
}

View File

@ -6,7 +6,18 @@ namespace PkmnLibSharp.Library.Items
{
public class ItemLibrary : PointerWrapper
{
private readonly Dictionary<string, Item> _cache = new Dictionary<string, Item>(StringComparer.InvariantCultureIgnoreCase);
private readonly Dictionary<string, Item> _cache =
new Dictionary<string, Item>(StringComparer.InvariantCultureIgnoreCase);
internal ItemLibrary(IntPtr ptr) : base(ptr)
{
}
public ItemLibrary(ulong initialCapacity) : base(
Creatureliblibrary.Generated.ItemLibrary.Construct(initialCapacity))
{
}
public ulong Count => Creatureliblibrary.Generated.ItemLibrary.GetCount(Ptr);
public void Insert(string key, Item item)
@ -26,13 +37,14 @@ namespace PkmnLibSharp.Library.Items
if (_cache.TryGetValue(key, out item))
return true;
var ptr = IntPtr.Zero;
if (Creatureliblibrary.Generated.ItemLibrary.TryGet(Ptr, key.ToPtr(), ref ptr) != MarshalHelper.True)
if (Creatureliblibrary.Generated.ItemLibrary.TryGet(Ptr, key.ToPtr(), ref ptr) != MarshalHelper.True)
return false;
if (TryResolvePointer(ptr, out item))
{
_cache.Add(key, item);
return true;
}
item = new Item(ptr);
_cache.Add(key, item);
return true;
@ -49,33 +61,21 @@ namespace PkmnLibSharp.Library.Items
_cache.Add(key, item);
return item;
}
item = new Item(ptr);
_cache.Add(key, item);
return item;
}
internal ItemLibrary(IntPtr ptr) : base(ptr)
{
}
public ItemLibrary(ulong initialCapacity) : base(
Creatureliblibrary.Generated.ItemLibrary.Construct(initialCapacity))
{
}
protected internal override void MarkAsDeleted()
{
base.MarkAsDeleted();
foreach (var item in _cache)
{
item.Value.MarkAsDeleted();
}
foreach (var item in _cache) item.Value.MarkAsDeleted();
}
protected override void DeletePtr()
{
Creatureliblibrary.Generated.ItemLibrary.Destruct(Ptr);
}
}
}

View File

@ -4,6 +4,6 @@ namespace PkmnLibSharp.Library.Moves
{
Physical = 0,
Special = 1,
Status = 2,
Status = 2
}
}

View File

@ -1,9 +1,8 @@
using System;
using System.Linq;
using Creatureliblibrary;
using Creatureliblibrary.Generated;
using Pkmnlib;
using PkmnLibSharp.Utilities;
using AttackCategory = Creatureliblibrary.AttackCategory;
namespace PkmnLibSharp.Library.Moves
{
@ -12,6 +11,10 @@ namespace PkmnLibSharp.Library.Moves
private string _name;
private string _secondaryEffectName;
internal MoveData(IntPtr ptr) : base(ptr)
{
}
public string Name => _name ??= AttackData.GetName(Ptr).PtrString();
public byte Type => AttackData.GetType(Ptr);
public MoveCategory Category => (MoveCategory) AttackData.GetCategory(Ptr);
@ -40,15 +43,11 @@ namespace PkmnLibSharp.Library.Moves
var f = flags.Select(x => x.ToPtr()).ToArray().ArrayPtr();
AttackData.Construct(ref ptr, name.ToPtr(), type, (AttackCategory) category, power, accuracy, baseUsage,
(Creatureliblibrary.AttackTarget) target, priority, effectChance, effectName.ToPtr(), pars,
(AttackTarget) target, priority, effectChance, effectName.ToPtr(), pars,
(ulong) parameters.Length, f, (ulong) flags.Length).Assert();
return new MoveData(ptr);
}
internal MoveData(IntPtr ptr) : base(ptr)
{
}
protected override void DeletePtr()
{
AttackData.Destruct(Ptr);

View File

@ -7,7 +7,13 @@ namespace PkmnLibSharp.Library.Moves
{
public class MoveLibrary : PointerWrapper
{
private readonly Dictionary<string, MoveData> _cache = new Dictionary<string, MoveData>(StringComparer.InvariantCultureIgnoreCase);
private readonly Dictionary<string, MoveData> _cache =
new Dictionary<string, MoveData>(StringComparer.InvariantCultureIgnoreCase);
internal MoveLibrary(IntPtr ptr) : base(ptr)
{
}
public ulong Count => AttackLibrary.GetCount(Ptr);
public void Insert(string key, MoveData move)
@ -27,13 +33,14 @@ namespace PkmnLibSharp.Library.Moves
if (_cache.TryGetValue(key, out move))
return true;
var ptr = IntPtr.Zero;
if (AttackLibrary.TryGet(Ptr, key.ToPtr(), ref ptr) != MarshalHelper.True)
if (AttackLibrary.TryGet(Ptr, key.ToPtr(), ref ptr) != MarshalHelper.True)
return false;
if (TryResolvePointer(ptr, out move))
{
_cache.Add(key, move);
return true;
}
move = new MoveData(ptr);
_cache.Add(key, move);
return true;
@ -50,6 +57,7 @@ namespace PkmnLibSharp.Library.Moves
_cache.Add(key, move);
return move;
}
move = new MoveData(ptr);
_cache.Add(key, move);
return move;
@ -61,18 +69,11 @@ namespace PkmnLibSharp.Library.Moves
AttackLibrary.Construct(ref ptr, defaultCapacity).Assert();
return new MoveLibrary(ptr);
}
internal MoveLibrary(IntPtr ptr) : base(ptr)
{
}
protected internal override void MarkAsDeleted()
{
base.MarkAsDeleted();
foreach (var moveData in _cache)
{
moveData.Value.MarkAsDeleted();
}
foreach (var moveData in _cache) moveData.Value.MarkAsDeleted();
}
protected override void DeletePtr()

View File

@ -13,6 +13,6 @@ namespace PkmnLibSharp.Library.Moves
AllOpponent = 8,
Any = 9,
RandomOpponent = 10,
Self = 11,
Self = 11
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using PkmnLibSharp.Utilities;
using Random = PkmnLibSharp.Utilities.Random;
namespace PkmnLibSharp.Library
{
@ -54,6 +55,11 @@ namespace PkmnLibSharp.Library
return ptr.PtrString();
}
public string GetRandomNatureName(Random random)
{
return Pkmnlib.Generated.NatureLibrary.GetRandomNatureName(Ptr, random.Ptr).PtrString();
}
protected override void DeletePtr()
{
Pkmnlib.Generated.NatureLibrary.Destruct(Ptr);

View File

@ -115,7 +115,7 @@ namespace PkmnLibSharp.Library
}
private PokemonLibrary(IntPtr ptr) : base(ptr)
internal PokemonLibrary(IntPtr ptr) : base(ptr)
{
}

View File

@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using Creatureliblibrary.Generated;
using Pkmnlib;
using Pkmnlib.Generated;
using PkmnLibSharp.Utilities;
using Gender = PkmnLibSharp.Battling.Gender;
using Random = PkmnLibSharp.Utilities.Random;
namespace PkmnLibSharp.Library
{
@ -68,6 +71,11 @@ namespace PkmnLibSharp.Library
CreatureSpecies.SetVariant(Ptr, s.ToPtr(), forme.Ptr).Assert();
}
public Gender GetRandomGender(Random random)
{
return (Gender) CreatureSpecies.GetRandomGender(Ptr, random.Ptr);
}
internal Species(IntPtr ptr) : base(ptr)
{

View File

@ -0,0 +1,24 @@
using System;
namespace PkmnLibSharp.Library
{
public class StatisticSet<T> where T : IComparable<T>
{
public T HP { get; set; }
public T Attack { get; set; }
public T Defense { get; set; }
public T SpecialAttack { get; set; }
public T SpecialDefense { get; set; }
public T Speed { get; set; }
public StatisticSet(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed)
{
HP = hp;
Attack = attack;
Defense = defense;
SpecialAttack = specialAttack;
SpecialDefense = specialDefense;
Speed = speed;
}
}
}

BIN
PkmnLibSharp/Native/libArubtils.so (Stored with Git LFS) Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
PkmnLibSharp/Native/libpkmnLib.so (Stored with Git LFS)

Binary file not shown.

View File

@ -0,0 +1,59 @@
namespace PkmnLibSharp.Utilities
{
public class Random : PointerWrapper
{
public Random() : base(Arbutils.Generated.Random.Construct())
{
}
public Random(ulong seed) : base(Arbutils.Generated.Random.ConstructWithSeed(seed))
{
}
public float GetFloat()
{
return Arbutils.Generated.Random.GetFloat(Ptr);
}
public double GetDouble()
{
return Arbutils.Generated.Random.GetDouble(Ptr);
}
public int Get()
{
return Arbutils.Generated.Random.Get(Ptr);
}
public int Get(int max)
{
return Arbutils.Generated.Random.GetWithMax(Ptr, max);
}
public int Get(int min, int max)
{
return Arbutils.Generated.Random.GetInLimits(Ptr, min, max);
}
public uint GetUnsigned()
{
return Arbutils.Generated.Random.GetUnsigned(Ptr);
}
public uint GetUnsigned(uint max)
{
return Arbutils.Generated.Random.GetUnsignedWithMax(Ptr, max);
}
public uint GetUnsigned(uint min, uint max)
{
return Arbutils.Generated.Random.GetUnsignedInLimits(Ptr, min, max);
}
protected override void DeletePtr()
{
Arbutils.Generated.Random.Destruct(Ptr);
}
}
}

View File

@ -0,0 +1 @@
{"enums":[],"functions":[{"filename":"Arbutils","name":"Arbutils_Random_Construct","parameters":[],"returns":"Random *"},{"filename":"Arbutils","name":"Arbutils_Random_ConstructWithSeed","parameters":[{"name":"seed","type":"long unsigned int"}],"returns":"Random *"},{"filename":"Arbutils","name":"Arbutils_Random_Destruct","parameters":[{"name":"p","type":"Random *"}],"returns":"void"},{"filename":"Arbutils","name":"Arbutils_Random_GetFloat","parameters":[{"name":"p","type":"Random *"}],"returns":"float"},{"filename":"Arbutils","name":"Arbutils_Random_GetDouble","parameters":[{"name":"p","type":"Random *"}],"returns":"double"},{"filename":"Arbutils","name":"Arbutils_Random_Get","parameters":[{"name":"p","type":"Random *"}],"returns":"int"},{"filename":"Arbutils","name":"Arbutils_Random_GetWithMax","parameters":[{"name":"p","type":"Random *"},{"name":"max","type":"int"}],"returns":"int"},{"filename":"Arbutils","name":"Arbutils_Random_GetInLimits","parameters":[{"name":"p","type":"Random *"},{"name":"min","type":"int"},{"name":"max","type":"int"}],"returns":"int"},{"filename":"Arbutils","name":"Arbutils_Random_GetUnsigned","parameters":[{"name":"p","type":"Random *"}],"returns":"unsigned int"},{"filename":"Arbutils","name":"Arbutils_Random_GetUnsignedWithMax","parameters":[{"name":"p","type":"Random *"},{"name":"max","type":"unsigned int"}],"returns":"unsigned int"},{"filename":"Arbutils","name":"Arbutils_Random_GetUnsignedInLimits","parameters":[{"name":"p","type":"Random *"},{"name":"min","type":"unsigned int"},{"name":"max","type":"unsigned int"}],"returns":"unsigned int"},{"filename":"Arbutils","name":"Arbutils_Random_GetSeed","parameters":[{"name":"p","type":"Random *"}],"returns":"long unsigned int"}]}

File diff suppressed because one or more lines are too long

View File

@ -62,6 +62,8 @@ def parse_type(type, enumSet):
return "byte"
if (type == "float"):
return "float"
if (type == "double"):
return "double"
if (type == "long unsigned int"):
return "ulong"
if (type == "long int"):
@ -112,23 +114,24 @@ def write_class(c, enumSet):
f.write("}\n")
def parse_create(data):
def parse_create(data, filepath):
enumSet = set()
for enum in data["enums"]:
write_enum(enum, enumSet)
classDict = dict()
for function in data["functions"]:
parse_function(function, classDict)
print("Registered {} classes.".format(len(classDict)))
print("Registered {} classes from file {}.".format(len(classDict), filepath))
for _, v in classDict.items():
write_class(v, enumSet)
def handle_file(filepath):
with open(filepath) as json_file:
data = json.load(json_file)
parse_create(data)
parse_create(data, filepath)
def main():
handle_file("arbutils.json")
handle_file("creaturelib.json")
handle_file("pkmnlib.json")

View File

@ -16,4 +16,8 @@
<ProjectReference Include="..\PkmnLibSharp\PkmnLibSharp.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Battling" />
</ItemGroup>
</Project>