From 683925430d90b96691b461458ab810037c39fb04 Mon Sep 17 00:00:00 2001 From: Garry Newman Date: Mon, 29 Apr 2019 11:33:08 +0100 Subject: [PATCH] Consume, Split, Transfer --- Facepunch.Steamworks/SteamInventory.cs | 9 +--- Facepunch.Steamworks/Structs/InventoryItem.cs | 41 +++++++++++++++++++ .../Structs/InventoryResult.cs | 33 ++++++++------- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/Facepunch.Steamworks/SteamInventory.cs b/Facepunch.Steamworks/SteamInventory.cs index ba3aa87..084b58f 100644 --- a/Facepunch.Steamworks/SteamInventory.cs +++ b/Facepunch.Steamworks/SteamInventory.cs @@ -145,14 +145,7 @@ internal static InventoryDef[] GetDefinitions() if ( !Internal.GetAllItems( ref sresult ) ) return null; - var result = new InventoryResult( sresult ); - - if ( !await result.WaitUntilReadyAsync() ) - { - return null; - } - - return result; + return await InventoryResult.GetAsync( sresult ); } } diff --git a/Facepunch.Steamworks/Structs/InventoryItem.cs b/Facepunch.Steamworks/Structs/InventoryItem.cs index 1643c5b..c33ba66 100644 --- a/Facepunch.Steamworks/Structs/InventoryItem.cs +++ b/Facepunch.Steamworks/Structs/InventoryItem.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Steamworks.Data; namespace Steamworks @@ -44,6 +45,46 @@ public struct InventoryItem /// public bool IsConsumed => (_flags & 1 << 9) != 0; + /// + /// Consumes items from a user's inventory. If the quantity of the given item goes to zero, it is permanently removed. + /// Once an item is removed it cannot be recovered.This is not for the faint of heart - if your game implements item removal at all, + /// a high-friction UI confirmation process is highly recommended.ConsumeItem can be restricted to certain item definitions or fully + /// blocked via the Steamworks website to minimize support/abuse issues such as the classic "my brother borrowed my laptop and deleted all of my rare items". + /// + public async Task Consume( int amount = 1 ) + { + var sresult = default( SteamInventoryResult_t ); + if ( !SteamInventory.Internal.ConsumeItem( ref sresult, Id, (uint)amount ) ) + return null; + + return await InventoryResult.GetAsync( sresult ); + } + + /// + /// Split stack into two items + /// + public async Task SplitStack( int quantity = 1 ) + { + var sresult = default( SteamInventoryResult_t ); + if ( !SteamInventory.Internal.TransferItemQuantity( ref sresult, Id, (uint)quantity, ulong.MaxValue ) ) + return null; + + return await InventoryResult.GetAsync( sresult ); + } + + /// + /// Transfer x quantity from this item to the target item + /// + public async Task TransferItemQuantity( InventoryItem toItem, int quantity ) + { + var sresult = default( SteamInventoryResult_t ); + if ( !SteamInventory.Internal.TransferItemQuantity( ref sresult, Id, (uint)quantity, toItem.Id ) ) + return null; + + return await InventoryResult.GetAsync( sresult ); + } + + internal static InventoryItem From( SteamItemDetails_t details ) { var i = new InventoryItem diff --git a/Facepunch.Steamworks/Structs/InventoryResult.cs b/Facepunch.Steamworks/Structs/InventoryResult.cs index 62eb875..0f0d7d3 100644 --- a/Facepunch.Steamworks/Structs/InventoryResult.cs +++ b/Facepunch.Steamworks/Structs/InventoryResult.cs @@ -8,23 +8,13 @@ namespace Steamworks public struct InventoryResult : IDisposable { internal SteamInventoryResult_t _id; - internal Result _result; + + public bool Expired { get; internal set; } - internal InventoryResult( SteamInventoryResult_t id ) + internal InventoryResult( SteamInventoryResult_t id, bool expired ) { _id = id; - _result = Result.Pending; - } - - internal async Task WaitUntilReadyAsync() - { - while ( _result == Result.Pending ) - { - _result = SteamInventory.Internal.GetResultStatus( _id ); - await Task.Delay( 10 ); - } - - return _result == Result.OK || _result == Result.Expired; + Expired = expired; } public int ItemCount @@ -71,6 +61,21 @@ public void Dispose() SteamInventory.Internal.DestroyResult( _id ); } + internal static async Task GetAsync( SteamInventoryResult_t sresult ) + { + var _result = Result.Pending; + while ( _result == Result.Pending ) + { + _result = SteamInventory.Internal.GetResultStatus( sresult ); + await Task.Delay( 10 ); + } + + if ( _result != Result.OK && _result != Result.Expired ) + return null; + + return new InventoryResult( sresult, _result == Result.Expired ); + } + /// /// Serialized result sets contain a short signature which can't be forged or replayed across different game sessions. /// A result set can be serialized on the local client, transmitted to other players via your game networking, and