From 65d55a95fa8cd716f3d5c5e8d8b5d6b9c92874cb Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 20 Sep 2022 18:03:53 +0200 Subject: [PATCH] Adds Item interface --- PkmnLibRSharp/FFI/StaticData/Item.cs | 32 ++++++ PkmnLibRSharp/StaticData/Item.cs | 115 +++++++++++++++++++++ PkmnLibRSharpTests/StaticData/ItemTests.cs | 31 ++++++ 3 files changed, 178 insertions(+) create mode 100644 PkmnLibRSharp/FFI/StaticData/Item.cs create mode 100644 PkmnLibRSharp/StaticData/Item.cs create mode 100644 PkmnLibRSharpTests/StaticData/ItemTests.cs diff --git a/PkmnLibRSharp/FFI/StaticData/Item.cs b/PkmnLibRSharp/FFI/StaticData/Item.cs new file mode 100644 index 0000000..53f66f5 --- /dev/null +++ b/PkmnLibRSharp/FFI/StaticData/Item.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.InteropServices; +using PkmnLibSharp.StaticData; + +namespace PkmnLibSharp.FFI.StaticData +{ + internal static class Item + { + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr item_new(IntPtr name, ItemCategory category, BattleItemCategory battleCategory, + int price, IntPtr flags, ulong flagsLength); + + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern void item_drop(IntPtr ptr); + + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern IntPtr item_name(IntPtr ptr); + + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern ItemCategory item_category(IntPtr ptr); + + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern BattleItemCategory item_battle_category(IntPtr ptr); + + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern int item_price(IntPtr ptr); + + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl)] + internal static extern byte item_has_flag(IntPtr p, IntPtr flag); + + } +} \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/Item.cs b/PkmnLibRSharp/StaticData/Item.cs new file mode 100644 index 0000000..42d8e8a --- /dev/null +++ b/PkmnLibRSharp/StaticData/Item.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; +using System.Linq; +using PkmnLibSharp.Utils; +using Interface = PkmnLibSharp.FFI.StaticData.Item; + +namespace PkmnLibSharp.StaticData +{ + /// + /// An item category defines which bag slot items are stored in. + /// + public enum ItemCategory : byte + { + /// + /// This is where most items should go. + /// + MiscItem, + + /// + /// Pokeballs are used for capturing Pokemons. + /// + Pokeball, + + /// + /// Medicine is used for healing HP, PP, and status effects + /// + Medicine, + + /// + /// Berry is used for all berries. + /// + Berry, + + /// + /// TMHM is used for Technical and Hidden Machines. + /// + TMHM, + + /// + /// Form Changer is used for items that change forms, such as mega stones. + /// + FormChanger, + + /// + /// Key Items are single stored items, generally used for story progression. + /// + KeyItem, + + /// + /// Mail is used for mail items. + /// + Mail, + } + + /// + /// A battle item category defines how the item is categorized when in battle. + /// + public enum BattleItemCategory : byte + { + /// + /// This item can't be used in battle. + /// + None, + + /// + /// This item is used for healing Pokemon. + /// + Healing, + + /// + /// This item is used for healing Pokemon from a status. + /// + StatusHealing, + + /// + /// This item is used for capturing Pokemon. + /// + Pokeball, + + /// + /// This item does not belong in above categories, but is still a battle item. + /// + MiscBattleItem, + } + + public class Item : ExternPointer + { + public class CacheData + { + public string? Name { get; internal set; } + public ItemCategory? Category { get; internal set; } + public BattleItemCategory? BattleCategory { get; internal set; } + public int? Price { get; internal set; } + } + + public Item(string name, ItemCategory category, BattleItemCategory battleItemCategory, int price, + IEnumerable flags) + { + var ptrArray = flags.Select(x => x.ToPtr()).ToArray(); + var ptrToPtrArray = ptrArray.ArrayPtr(); + var ptr = Interface.item_new(name.ToPtr(), category, battleItemCategory, price, ptrToPtrArray, + (ulong)ptrArray.Length); + InitializePointer(ptr, true); + } + + public string Name => Cache.Name ??= Interface.item_name(Ptr).PtrString()!; + public ItemCategory Category => Cache.Category ??= Interface.item_category(Ptr); + public BattleItemCategory BattleCategory => Cache.BattleCategory ??= Interface.item_battle_category(Ptr); + public int Price => Cache.Price ??= Interface.item_price(Ptr); + + public bool HasFlag(string flag) => Interface.item_has_flag(Ptr, flag.ToPtr()) == 1; + + protected override CacheData CreateCache() => new CacheData(); + protected override void Destructor() => Interface.item_drop(Ptr); + } +} \ No newline at end of file diff --git a/PkmnLibRSharpTests/StaticData/ItemTests.cs b/PkmnLibRSharpTests/StaticData/ItemTests.cs new file mode 100644 index 0000000..d423bab --- /dev/null +++ b/PkmnLibRSharpTests/StaticData/ItemTests.cs @@ -0,0 +1,31 @@ +using System; +using NUnit.Framework; +using PkmnLibSharp.StaticData; + +namespace PkmnLibRSharpTests.StaticData +{ + public class ItemTests + { + [Test] + public void BasicTests() + { + using var item = new Item("foobar", ItemCategory.Mail, BattleItemCategory.StatusHealing, 500, + Array.Empty()); + Assert.AreEqual("foobar", item.Name); + Assert.AreEqual(ItemCategory.Mail, item.Category); + Assert.AreEqual(BattleItemCategory.StatusHealing, item.BattleCategory); + Assert.AreEqual(500, item.Price); + } + + [Test] + public void FlagTests() + { + using var item = new Item("foobar", ItemCategory.Mail, BattleItemCategory.StatusHealing, 500, + new []{"foo", "zet"}); + Assert.That(item.HasFlag("foo")); + Assert.That(item.HasFlag("zet")); + Assert.That(!item.HasFlag("bar")); + } + + } +} \ No newline at end of file