using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Steamworks.Data
{
///
/// Represents a Steam Achievement.
///
public struct Achievement
{
internal string Value;
public Achievement( string name )
{
Value = name;
}
public override string ToString() => Value;
///
/// Gets whether or not the achievement has been unlocked.
///
public bool State
{
get
{
var state = false;
SteamUserStats.Internal?.GetAchievement( Value, ref state );
return state;
}
}
///
/// Gets the identifier of the achievement. This is the "API Name" on Steamworks.
///
public string Identifier => Value;
///
/// Gets the display name of the achievement.
///
public string? Name => SteamUserStats.Internal?.GetAchievementDisplayAttribute( Value, "name" );
///
/// Gets the description of the achievement.
///
public string? Description => SteamUserStats.Internal?.GetAchievementDisplayAttribute( Value, "desc" );
///
/// If is , this value represents the time that the achievement was unlocked.
///
public DateTime? UnlockTime
{
get
{
var state = false;
uint time = 0;
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetAchievementAndUnlockTime( Value, ref state, ref time ) || !state )
return null;
return Epoch.ToDateTime( time );
}
}
///
/// Gets the icon of the achievement. This can return a null image even though the image exists if the image
/// hasn't been downloaded by Steam yet. You should use if you want to wait for the image to be downloaded.
///
public Image? GetIcon()
{
if (SteamUserStats.Internal is null) { return null; }
return SteamUtils.GetImage( SteamUserStats.Internal.GetAchievementIcon( Value ) );
}
///
/// Gets the icon of the achievement, yielding until the icon is received or the is reached.
///
/// The timeout in milliseconds before the request will be canceled. Defaults to 5000.
public async Task GetIconAsync( int timeout = 5000 )
{
if (SteamUserStats.Internal is null) { return null; }
var i = SteamUserStats.Internal.GetAchievementIcon( Value );
if ( i != 0 ) return SteamUtils.GetImage( i );
var ident = Identifier;
bool gotCallback = false;
void f( string x, int icon )
{
if ( x != ident ) return;
i = icon;
gotCallback = true;
}
try
{
SteamUserStats.OnAchievementIconFetched += f;
int waited = 0;
while ( !gotCallback )
{
await Task.Delay( 10 );
waited += 10;
// Time out after x milliseconds
if ( waited > timeout )
return null;
}
if ( i == 0 ) return null;
return SteamUtils.GetImage( i );
}
finally
{
SteamUserStats.OnAchievementIconFetched -= f;
}
}
///
/// Gets a decimal (0-1) representing the global amount of users who have unlocked the specified achievement, or -1 if no data available.
///
public float GlobalUnlocked
{
get
{
float pct = 0;
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetAchievementAchievedPercent( Value, ref pct ) )
return -1.0f;
return pct / 100.0f;
}
}
///
/// Unlock this achievement.
///
public bool Trigger( bool apply = true )
{
if (SteamUserStats.Internal is null) { return false; }
var r = SteamUserStats.Internal.SetAchievement( Value );
if ( apply && r )
{
SteamUserStats.Internal.StoreStats();
}
return r;
}
///
/// Reset this achievement to be locked.
///
public bool Clear()
{
if (SteamUserStats.Internal is null) { return false; }
return SteamUserStats.Internal.ClearAchievement( Value );
}
}
}