Skip to content
43 changes: 37 additions & 6 deletions S1API/Products/CocaineDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,65 @@
using S1CocaineDefinition = ScheduleOne.Product.CocaineDefinition;
#endif

using System.Collections.Generic;
using S1API.Internal.Utils;
using S1API.Items;

namespace S1API.Products
{
/// <summary>
/// Represents the definition of a Cocaine product.
/// Represents the definition of a cocaine product within the system.
/// </summary>
public class CocaineDefinition : ProductDefinition
{
/// <summary>
/// INTERNAL: Strongly typed access to the CocaineDefinition.
/// INTERNAL: Strongly typed access to the CocaineDefinition within the Schedule One framework.
/// </summary>
internal S1CocaineDefinition S1CocaineDefinition =>
CrossType.As<S1CocaineDefinition>(S1ItemDefinition);

/// <summary>
/// Creates a new cocaine product definition.
/// Represents the definition of a Cocaine product.
/// </summary>
/// <param name="definition">The original in-game cocaine definition.</param>
internal CocaineDefinition(S1CocaineDefinition definition)
: base(definition) { }
: base(definition)
{
}

/// <summary>
/// Creates an instance of this cocaine product.
/// Creates an instance of this cocaine product with the specified quantity.
/// </summary>
/// <param name="quantity">The quantity of the product to create. Defaults to 1.</param>
/// <returns>An instance of the cocaine product with the specified quantity.</returns>
public override ItemInstance CreateInstance(int quantity = 1) =>
new ProductInstance(CrossType.As<ProductItemInstance>(
S1CocaineDefinition.GetDefaultInstance(quantity)));

/// <summary>
/// Retrieves a list of properties associated with the current cocaine product definition.
/// </summary>
/// <returns>A list of properties specific to the cocaine product definition.</returns>
#if IL2CPPBEPINEX || IL2CPPMELON
public List<Il2CppScheduleOne.Properties.Property> GetProperties()
#else
public List<ScheduleOne.Properties.Property> GetProperties()
#endif
{
#if IL2CPPBEPINEX || IL2CPPMELON
var result = new List<Il2CppScheduleOne.Properties.Property>();
#else
var result = new List<ScheduleOne.Properties.Property>();
#endif
var list = S1CocaineDefinition?.Properties;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
result.Add(list[i]);
}
}
return result;
}
}

}
46 changes: 40 additions & 6 deletions S1API/Products/MethDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,68 @@
using S1MethDefinition = ScheduleOne.Product.MethDefinition;
#endif

using System.Collections.Generic;
using S1API.Internal.Utils;
using S1API.Items;

namespace S1API.Products
{
/// <summary>
/// Represents the definition of a Meth product.
/// Represents the definition of a Meth product in the product framework.
/// </summary>
/// <remarks>
/// Provides methods for retrieving properties and creating instances of meth products. This class extends the base functionality provided by <see cref="ProductDefinition"/>.
/// </remarks>
public class MethDefinition : ProductDefinition
{
/// <summary>
/// INTERNAL: Strongly typed access to the MethDefinition.
/// INTERNAL: Strongly typed access to S1MethDefinition, representing the Il2CppScheduleOne.Product.MethDefinition entity.
/// </summary>
internal S1MethDefinition S1MethDefinition =>
CrossType.As<S1MethDefinition>(S1ItemDefinition);

/// <summary>
/// Creates a new meth product definition.
/// Represents the definition of a Meth product.
/// </summary>
/// <param name="definition">The original in-game meth definition.</param>
internal MethDefinition(S1MethDefinition definition)
: base(definition) { }
: base(definition)
{
}

/// <summary>
/// Creates an instance of this meth product.
/// Creates an instance of this meth product with a specified quantity.
/// </summary>
/// <param name="quantity">The quantity of the meth product to instantiate. Defaults to 1 if not provided.</param>
/// <returns>An instance of the meth product as a <see cref="ItemInstance"/>.</returns>
public override ItemInstance CreateInstance(int quantity = 1) =>
new ProductInstance(CrossType.As<ProductItemInstance>(
S1MethDefinition.GetDefaultInstance(quantity)));

/// <summary>
/// Retrieves the list of properties associated with the meth product definition.
/// </summary>
/// <returns>A list of properties that belong to the meth product definition.</returns>
#if IL2CPPBEPINEX || IL2CPPMELON
public List<Il2CppScheduleOne.Properties.Property> GetProperties()
#else
public List<ScheduleOne.Properties.Property> GetProperties()
#endif
{
#if IL2CPPBEPINEX || IL2CPPMELON
var result = new List<Il2CppScheduleOne.Properties.Property>();
#else
var result = new List<ScheduleOne.Properties.Property>();
#endif
var list = S1MethDefinition?.Properties;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
result.Add(list[i]);
}
}

return result;
}
}
}
18 changes: 15 additions & 3 deletions S1API/Products/ProductDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using S1Product = ScheduleOne.Product;
#endif

using System.Collections.Generic;
using S1API.Internal.Utils;
using S1API.Items;
using UnityEngine;
Expand All @@ -26,8 +27,11 @@
/// INTERNAL: Creates a product definition from the in-game product definition.
/// </summary>
/// <param name="productDefinition"></param>
internal ProductDefinition(S1Product.ProductDefinition productDefinition) : base(productDefinition) { }

#if IL2CPPBEPINEX || IL2CPPMELON
internal ProductDefinition(Il2CppScheduleOne.ItemFramework.ItemDefinition productDefinition) : base(productDefinition) { }
#else
internal ProductDefinition(ScheduleOne.ItemFramework.ItemDefinition productDefinition) : base(productDefinition) { }

Check warning on line 33 in S1API/Products/ProductDefinition.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

Non-nullable field 'properties' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
#endif
/// <summary>
/// The price associated with this product.
/// </summary>
Expand All @@ -49,6 +53,14 @@
{
get { return S1ProductDefinition.Icon; }
}
#if IL2CPPBEPINEX || IL2CPPMELON
private List<Il2CppScheduleOne.Properties.Property> properties; // or however properties are stored
public List<Il2CppScheduleOne.Properties.Property> Properties; // or however properties are stored
#else
private List<ScheduleOne.Properties.Property> properties; // or however properties are stored
public IReadOnlyList<ScheduleOne.Properties.Property> Properties => properties.AsReadOnly();
#endif

}

}
}
15 changes: 12 additions & 3 deletions S1API/Products/ProductDefinitionWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@

#if (IL2CPPMELON || IL2CPPBEPINEX)
using S1Product = Il2CppScheduleOne.Product;

#else
using S1Product = ScheduleOne.Product;
#endif

namespace S1API.Products
{
/// <summary>
/// INTERNAL: A wrapper class for converting a product definition to its proper dedicated class.
/// Provides functionality to wrap and convert generic product definitions into their specific type-derived definitions.
/// </summary>
internal static class ProductDefinitionWrapper
public static class ProductDefinitionWrapper
{
internal static ProductDefinition Wrap(ProductDefinition def)
/// <summary>
/// Converts a generic <see cref="ProductDefinition"/> into its corresponding typed wrapper.
/// </summary>
/// <param name="def">The raw product definition to be processed and converted.</param>
/// <returns>A wrapped instance of <see cref="ProductDefinition"/> with type-specific methods and properties, or the input definition if no specific wrapper applies.</returns>
public static ProductDefinition Wrap(ProductDefinition def)
{
var item = def.S1ItemDefinition;
if (CrossType.Is<S1Product.WeedDefinition>(item, out var weed))
return new WeedDefinition(weed);

if (CrossType.Is<S1Product.MethDefinition>(item, out var meth))
return new MethDefinition(meth);

if (CrossType.Is<S1Product.CocaineDefinition>(item, out var coke))
return new CocaineDefinition(coke);

return def;
}
}
Expand Down
29 changes: 27 additions & 2 deletions S1API/Products/ProductInstance.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#if (IL2CPPMELON || IL2CPPBEPINEX)
using S1Product = Il2CppScheduleOne.Product;
using Il2CppScheduleOne.ItemFramework;

#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX)
using S1Product = ScheduleOne.Product;
using ScheduleOne.ItemFramework;
#endif

using System.Collections.Generic;
using S1API.Internal.Utils;
using S1API.Items;
using ItemInstance = S1API.Items.ItemInstance;

namespace S1API.Products
{
Expand All @@ -24,7 +28,9 @@
/// INTERNAL: Creates a product instance from the in-game product instance.
/// </summary>
/// <param name="productInstance"></param>
internal ProductInstance(S1Product.ProductItemInstance productInstance) : base(productInstance) { }
internal ProductInstance(S1Product.ProductItemInstance productInstance) : base(productInstance)
{
}

/// <summary>
/// Whether this product is currently packaged or not.
Expand All @@ -37,5 +43,24 @@
/// </summary>
public PackagingDefinition AppliedPackaging =>
new PackagingDefinition(S1ProductInstance.AppliedPackaging);

/// <summary>
/// The quality of this product instance.
/// </summary>
public Quality Quality => S1ProductInstance.Quality.ToAPI();

// Expose the underlying definition's properties (if S1ProductInstance.Definition is available)

// Add Definition property if you don't have one yet

#if IL2CPPBEPINEX || IL2CPPMELON
public IReadOnlyList<Il2CppScheduleOne.Properties.Property> Properties => Definition.Properties;
public ProductDefinition Definition => new ProductDefinition(S1ProductInstance.Definition);

Check warning on line 58 in S1API/Products/ProductInstance.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductInstance.Definition' hides inherited member 'ItemInstance.Definition'. Use the new keyword if hiding was intended.
#else
public IReadOnlyList<ScheduleOne.Properties.Property> Properties => Definition.Properties;
public ProductDefinition Definition => new ProductDefinition(S1ProductInstance.Definition);

Check warning on line 61 in S1API/Products/ProductInstance.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductInstance.Definition' hides inherited member 'ItemInstance.Definition'. Use the new keyword if hiding was intended.

Check warning on line 61 in S1API/Products/ProductInstance.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductInstance.Definition' hides inherited member 'ItemInstance.Definition'. Use the new keyword if hiding was intended.

#endif

}
}
86 changes: 86 additions & 0 deletions S1API/Products/Quality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#if IL2CPPBEPINEX || IL2CPPMELON
using InternalQuality = Il2CppScheduleOne.ItemFramework.EQuality;
#else
using InternalQuality = ScheduleOne.ItemFramework.EQuality;
#endif
namespace S1API.Products
{
/// <summary>
/// Represents the quality levels for items.
/// </summary>
/// <remarks>
/// This enumeration defines various quality tiers that items can belong to. Each tier represents a specific
/// standard or grade, ranging from the lowest to the highest.
/// </remarks>
public enum Quality
{
/// <summary>
/// Represents the lowest quality level, indicating an item of no value or unusable condition.
/// </summary>
Trash = 0,

/// <summary>
/// Represents a quality level that is below standard but better than trash-quality.
/// </summary>
Poor = 1,

/// <summary>
/// Represents a standard level of quality in the predefined quality enumeration.
/// Typically used to indicate an average or commonly acceptable quality level.
/// </summary>
Standard = 2,

/// <summary>
/// Represents a higher-tier quality level compared to lower
Premium = 3,

Check warning on line 35 in S1API/Products/Quality.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'

Check warning on line 35 in S1API/Products/Quality.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'

Check warning on line 35 in S1API/Products/Quality.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'

/// <summary>
/// Represents the highest level of quality, denoted as "Heavenly".
Heavenly = 4

Check warning on line 39 in S1API/Products/Quality.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'

Check warning on line 39 in S1API/Products/Quality.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'

Check warning on line 39 in S1API/Products/Quality.cs

View workflow job for this annotation

GitHub Actions / Verify Successful Build

XML comment has badly formed XML -- 'Expected an end tag for element 'summary'.'
}

/// <summary>
/// Provides extension methods for converting between <see cref="Il2CppScheduleOne.ItemFramework.EQuality"/> and
/// <see cref="S1API.Products.Quality"/> enumerations.
/// </summary>
internal static class QualityExtensions
{
/// <summary>
/// Converts an instance of <see cref="Il2CppScheduleOne.ItemFramework.EQuality"/> to its corresponding
/// <see cref="S1API.Products.Quality"/> representation.
/// </summary>
/// <param name="quality">The <see cref="Il2CppScheduleOne.ItemFramework.EQuality"/> instance to convert.</param>
/// <returns>A <see cref="S1API.Products.Quality"/> value that represents the converted quality.</returns>
internal static Quality ToAPI(this InternalQuality quality)
{
return quality switch
{
InternalQuality.Trash => Quality.Trash,
InternalQuality.Poor => Quality.Poor,
InternalQuality.Standard => Quality.Standard,
InternalQuality.Premium => Quality.Premium,
InternalQuality.Heavenly => Quality.Heavenly,
_ => Quality.Trash,
};
}

/// <summary>
/// Converts an instance of the <see cref="Quality"/> enum to its corresponding
/// <see cref="InternalQuality"/> enum representation.
/// </summary>
/// <param name="quality">The <see cref="Quality"/> enum value to convert.</param>
/// <returns>The corresponding <see cref="InternalQuality"/> enum value.</returns>
internal static InternalQuality ToInternal(this Quality quality)
{
return quality switch
{
Quality.Trash => InternalQuality.Trash,
Quality.Poor => InternalQuality.Poor,
Quality.Standard => InternalQuality.Standard,
Quality.Premium => InternalQuality.Premium,
Quality.Heavenly => InternalQuality.Heavenly,
_ => InternalQuality.Trash,
};
}
}
}
Loading
Loading