Files
LuaCsForBarotraumaEP/Libraries/Facepunch.Steamworks/Interfaces/Inventory.Definition.cs
2019-03-18 20:39:27 +02:00

366 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using SteamNative;
namespace Facepunch.Steamworks
{
public partial class Inventory
{
/// <summary>
/// An item definition. This describes an item in your Steam inventory, but is
/// not unique to that item. For example, this might be a tshirt, but you might be able to own
/// multiple tshirts.
/// </summary>
public class Definition
{
internal Inventory inventory;
public int Id { get; private set; }
public string Name { get; set; }
public string Description { get; set; }
/// <summary>
/// URL to an image specified by the schema, else empty
/// </summary>
public string IconUrl { get; set; }
/// <summary>
/// URL to an image specified by the schema, else empty
/// </summary>
public string IconLargeUrl { get; set; }
/// <summary>
/// Type can be whatever the schema defines.
/// </summary>
public string Type { get; set; }
/// <summary>
/// If this item can be created using other items this string will contain a comma seperated
/// list of definition ids that can be used, ie "100,101;102x5;103x3,104x3"
/// </summary>
public string ExchangeSchema { get; set; }
/// <summary>
/// A list of recepies for creating this item. Can be null if none.
/// </summary>
public Recipe[] Recipes { get; set; }
/// <summary>
/// A list of recepies we're included in
/// </summary>
public Recipe[] IngredientFor { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
/// <summary>
/// The raw contents of price_category from the schema
/// </summary>
public string PriceCategory { get; set; }
/// <summary>
/// The dollar price from PriceRaw
/// </summary>
public double PriceDollars { get; internal set; }
/// <summary>
/// The price in the local player's currency. The local player's currency
/// is available in Invetory.Currency
/// </summary>
public double LocalPrice { get; internal set; }
/// <summary>
/// Local Price but probably how you want to display it (ie, $3.99, £1.99 etc )
/// </summary>
public string LocalPriceFormatted { get; internal set; }
/// <summary>
/// Returns true if this item can be sold on the marketplace
/// </summary>
public bool Marketable { get; set; }
public bool IsGenerator
{
get { return Type == "generator"; }
}
private Dictionary<string, string> customProperties;
internal Definition( Inventory i, int id )
{
inventory = i;
Id = id;
SetupCommonProperties();
UpdatePrice();
}
/// <summary>
/// If you're manually occupying the Definition (because maybe you're on a server
/// and want to hack around the fact that definitions aren't presented to you),
/// you can use this to set propertis.
/// </summary>
public void SetProperty( string name, string value )
{
if ( customProperties == null )
customProperties = new Dictionary<string, string>();
if ( !customProperties.ContainsKey( name ) )
customProperties.Add( name, value );
else
customProperties[name] = value;
}
/// <summary>
/// Read a raw property from the definition schema
/// </summary>
public T GetProperty<T>( string name )
{
string val = GetStringProperty( name );
if ( string.IsNullOrEmpty( val ) )
return default( T );
try
{
return (T)Convert.ChangeType( val, typeof( T ) );
}
catch ( System.Exception )
{
return default( T );
}
}
/// <summary>
/// Read a raw property from the definition schema
/// </summary>
public string GetStringProperty( string name )
{
string val = string.Empty;
if ( customProperties != null && customProperties.ContainsKey( name ) )
return customProperties[name];
if ( !inventory.inventory.GetItemDefinitionProperty( Id, name, out val ) )
return string.Empty;
return val;
}
/// <summary>
/// Read a raw property from the definition schema
/// </summary>
public bool GetBoolProperty( string name )
{
string val = GetStringProperty( name );
if ( val.Length == 0 ) return false;
if ( val[0] == '0' || val[0] == 'F'|| val[0] == 'f' ) return false;
return true;
}
internal void SetupCommonProperties()
{
Name = GetStringProperty( "name" );
Description = GetStringProperty( "description" );
Created = GetProperty<DateTime>( "timestamp" );
Modified = GetProperty<DateTime>( "modified" );
ExchangeSchema = GetStringProperty( "exchange" );
IconUrl = GetStringProperty( "icon_url" );
IconLargeUrl = GetStringProperty( "icon_url_large" );
Type = GetStringProperty( "type" );
PriceCategory = GetStringProperty( "price_category" );
Marketable = GetBoolProperty( "marketable" );
if ( !string.IsNullOrEmpty( PriceCategory ) )
{
PriceDollars = PriceCategoryToFloat( PriceCategory );
}
}
/// <summary>
/// Trigger an item drop. Call this when it's a good time to award
/// an item drop to a player. This won't automatically result in giving
/// an item to a player. Just call it every minute or so, or on launch.
/// ItemDefinition is usually a generator
/// </summary>
public void TriggerItemDrop()
{
inventory.TriggerItemDrop( Id );
}
/// <summary>
/// Trigger a promo item drop. You can call this at startup, it won't
/// give users multiple promo drops.
/// </summary>
public void TriggerPromoDrop()
{
inventory.TriggerPromoDrop( Id );
}
internal void Link( Definition[] definitions )
{
LinkExchange( definitions );
}
private void LinkExchange( Definition[] definitions )
{
if ( string.IsNullOrEmpty( ExchangeSchema ) ) return;
var parts = ExchangeSchema.Split( new[] { ';' }, StringSplitOptions.RemoveEmptyEntries );
Recipes = parts.Select( x => Recipe.FromString( x, definitions, this ) ).ToArray();
}
internal void InRecipe( Recipe r )
{
if ( IngredientFor == null )
IngredientFor = new Recipe[0];
var list = new List<Recipe>( IngredientFor );
list.Add( r );
IngredientFor = list.ToArray();
}
internal void UpdatePrice()
{
if ( inventory.inventory.GetItemPrice( Id, out ulong price) )
{
LocalPrice = price / 100.0;
LocalPriceFormatted = Utility.FormatPrice( inventory.Currency, price );
}
else
{
LocalPrice = 0;
LocalPriceFormatted = null;
}
}
}
/// <summary>
/// Trigger a promo item drop. You can call this at startup, it won't
/// give users multiple promo drops.
/// </summary>
public void TriggerPromoDrop( int definitionId )
{
SteamNative.SteamInventoryResult_t result = 0;
inventory.AddPromoItem( ref result, definitionId );
inventory.DestroyResult( result );
}
/// <summary>
/// Trigger an item drop for this user. This is for timed drops. For promo
/// drops use TriggerPromoDrop.
/// </summary>
public void TriggerItemDrop( int definitionId )
{
SteamNative.SteamInventoryResult_t result = 0;
inventory.TriggerItemDrop( ref result, definitionId );
inventory.DestroyResult( result );
}
/// <summary>
/// Grant all promotional items the user is eligible for.
/// </summary>
public void GrantAllPromoItems()
{
SteamNative.SteamInventoryResult_t result = 0;
inventory.GrantPromoItems( ref result );
inventory.DestroyResult( result );
}
/// <summary>
/// Represents a crafting recepie which was defined using the exchange
/// section in the item schema.
/// </summary>
public struct Recipe
{
public struct Ingredient
{
/// <summary>
/// The definition ID of the ingredient.
/// </summary>
public int DefinitionId;
/// <summary>
/// If we don't know about this item definition this might be null.
/// In which case, DefinitionId should still hold the correct id.
/// </summary>
public Definition Definition;
/// <summary>
/// The amount of this item needed. Generally this will be 1.
/// </summary>
public int Count;
internal static Ingredient FromString( string part, Definition[] definitions )
{
var i = new Ingredient();
i.Count = 1;
try
{
if ( part.Contains( 'x' ) )
{
var idx = part.IndexOf( 'x' );
int count = 0;
if ( int.TryParse( part.Substring( idx + 1 ), out count ) )
i.Count = count;
part = part.Substring( 0, idx );
}
i.DefinitionId = int.Parse( part );
i.Definition = definitions.FirstOrDefault( x => x.Id == i.DefinitionId );
}
catch ( System.Exception )
{
return i;
}
return i;
}
}
/// <summary>
/// The item that this will create.
/// </summary>
public Definition Result;
/// <summary>
/// The items, with quantity required to create this item.
/// </summary>
public Ingredient[] Ingredients;
internal static Recipe FromString( string part, Definition[] definitions, Definition Result )
{
var r = new Recipe();
r.Result = Result;
var parts = part.Split( new[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
r.Ingredients = parts.Select( x => Ingredient.FromString( x, definitions ) ).Where( x => x.DefinitionId != 0 ).ToArray();
foreach ( var i in r.Ingredients )
{
if ( i.Definition == null )
continue;
i.Definition.InRecipe( r );
}
return r;
}
}
}
}