Skip to content
20 changes: 0 additions & 20 deletions S1API/Internal/Patches/QuestPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,26 +93,6 @@ private static void QuestsLoaderLoad(S1Loaders.QuestsLoader __instance, string m
}
}

/// <summary>
/// Patching performed for when stale files are deleted.
/// </summary>
/// <param name="__instance">Instance of the quest manager.</param>
/// <param name="parentFolderPath">Path to the base Quest folder.</param>
[HarmonyPatch(typeof(S1Quests.QuestManager), "DeleteUnapprovedFiles")]
[HarmonyPostfix]
private static void QuestManagerDeleteUnapprovedFiles(S1Quests.QuestManager __instance, string parentFolderPath)
{
string questFolder = Path.Combine(parentFolderPath, "Quests");
string?[] existingQuests = QuestManager.Quests.Select(quest => quest.SaveFolder).ToArray();

string[] unapprovedQuestDirectories = Directory.GetDirectories(questFolder)
.Where(directory => directory.StartsWith("Quest_") && !existingQuests.Contains(directory))
.ToArray();

foreach (string unapprovedQuestDirectory in unapprovedQuestDirectories)
Directory.Delete(unapprovedQuestDirectory, true);
}

[HarmonyPatch(typeof(S1Quests.Quest), "Start")]
[HarmonyPrefix]
private static void QuestStart(S1Quests.Quest __instance) =>
Expand Down
34 changes: 28 additions & 6 deletions S1API/Products/CocaineDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,61 @@
#if (IL2CPPMELON)
using Il2CppScheduleOne.Product;
using S1CocaineDefinition = Il2CppScheduleOne.Product.CocaineDefinition;
using S1Properties = Il2CppScheduleOne.Properties;
#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX)
using ScheduleOne.Product;
using S1CocaineDefinition = ScheduleOne.Product.CocaineDefinition;
using S1Properties = ScheduleOne.Properties;
#endif

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

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

/// <summary>
/// Creates a new cocaine product definition.
/// Represents the definition of a cocaine product within the system.
/// </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 product definition with the specified quantity.
/// </summary>
/// <param name="quantity">The quantity of the product to instantiate. Defaults to 1 if not specified.</param>
/// <returns>An <see cref="ItemInstance"/> representing the instantiated 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 this product definition.
/// </summary>
/// <returns>A list of properties for the product.</returns>
public List<S1Properties.Property> GetProperties()
{
var result = new List<S1Properties.Property>();
var list = S1CocaineDefinition?.Properties;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
result.Add(list[i]);
}
return result;
}
}
}
35 changes: 28 additions & 7 deletions S1API/Products/MethDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,60 @@
#if (IL2CPPMELON)
using Il2CppScheduleOne.Product;
using S1MethDefinition = Il2CppScheduleOne.Product.MethDefinition;
using S1Properties = Il2CppScheduleOne.Properties;
#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX)
using ScheduleOne.Product;
using S1MethDefinition = ScheduleOne.Product.MethDefinition;
using S1Properties = ScheduleOne.Properties;
#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 within the ScheduleOne product framework.
/// </summary>
public class MethDefinition : ProductDefinition
{
/// <summary>
/// INTERNAL: Strongly typed access to the MethDefinition.
/// INTERNAL: Strongly typed access to S1MethDefinition.
/// </summary>
internal S1MethDefinition S1MethDefinition =>
CrossType.As<S1MethDefinition>(S1ItemDefinition);

/// <summary>
/// Creates a new meth product definition.
/// Represents the definition of a Meth product in the product framework.
/// </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 the specified quantity.
/// </summary>
/// <param name="quantity">The quantity of the product instance to create. Defaults to 1 if not specified.</param>
/// <returns>An instance of <see cref="ItemInstance"/> representing the created meth product.</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 defined for the meth product.</returns>
public List<S1Properties.Property> GetProperties()
{
var result = new List<S1Properties.Property>();
var list = S1MethDefinition?.Properties;
if (list != null)
{
for (int i = 0; i < list.Count; i++)
result.Add(list[i]);
}
return result;
}
}
}
22 changes: 19 additions & 3 deletions S1API/Products/ProductDefinition.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#if (IL2CPPMELON)
using Il2CppInterop.Runtime.InteropTypes;
using S1Product = Il2CppScheduleOne.Product;
using ItemFramework = Il2CppScheduleOne.ItemFramework;
using Properties = Il2CppScheduleOne.Properties;
#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX)
using S1Product = ScheduleOne.Product;
using ItemFramework = ScheduleOne.ItemFramework;
using Properties = ScheduleOne.Properties;
#endif

using System.Collections.Generic;
using S1API.Internal.Utils;
using S1API.Items;
using UnityEngine;
Expand All @@ -26,8 +31,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 IL2CPPMELON
internal ProductDefinition(ItemFramework.ItemDefinition productDefinition) : base(productDefinition) { }
#else
internal ProductDefinition(ItemFramework.ItemDefinition productDefinition) : base(productDefinition) { }

Check warning on line 37 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.

Check warning on line 37 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 @@ -45,10 +53,18 @@
/// <summary>
/// Gets the in-game icon associated with the product.
/// </summary>
public Sprite Icon

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

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductDefinition.Icon' hides inherited member 'ItemDefinition.Icon'. Use the new keyword if hiding was intended.

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

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductDefinition.Icon' hides inherited member 'ItemDefinition.Icon'. Use the new keyword if hiding was intended.

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

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductDefinition.Icon' hides inherited member 'ItemDefinition.Icon'. Use the new keyword if hiding was intended.

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

View workflow job for this annotation

GitHub Actions / Verify Successful Build

'ProductDefinition.Icon' hides inherited member 'ItemDefinition.Icon'. Use the new keyword if hiding was intended.
{
get { return S1ProductDefinition.Icon; }
}
#if IL2CPPMELON
private List<Properties.Property> properties; // or however properties are stored
public List<Properties.Property> Properties; // or however properties are stored
#else
private List<Properties.Property> properties; // or however properties are stored

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

View workflow job for this annotation

GitHub Actions / Verify Successful Build

Field 'ProductDefinition.properties' is never assigned to, and will always have its default value null

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

View workflow job for this annotation

GitHub Actions / Verify Successful Build

Field 'ProductDefinition.properties' is never assigned to, and will always have its default value null
public IReadOnlyList<Properties.Property> Properties => properties.AsReadOnly();
#endif

}

}
}
17 changes: 12 additions & 5 deletions S1API/Products/ProductDefinitionWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
using S1API.Internal.Utils;

#if (IL2CPPMELON)
using S1Product = Il2CppScheduleOne.Product;
#else
#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX)
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
57 changes: 44 additions & 13 deletions S1API/Products/ProductInstance.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,72 @@
#if (IL2CPPMELON)
#if (IL2CPPMELON )
using S1Product = Il2CppScheduleOne.Product;
using S1Properties = Il2CppScheduleOne.Properties;
#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX)
using S1Product = ScheduleOne.Product;
using S1Properties = ScheduleOne.Properties;
#endif

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

using S1ItemInstance = S1API.Items.ItemInstance;
namespace S1API.Products
{
/// <summary>
/// Represents an instance of a product in the game.
/// </summary>
public class ProductInstance : ItemInstance
/// <remarks>
/// This class defines specific properties and behaviors for a product instance,
/// such as quality, packaging, and definition, derived from the S1API's item instance structure.
/// </remarks>
public class ProductInstance : S1ItemInstance
{
/// <summary>
/// INTERNAL: The stored reference to the in-game product instance.
/// INTERNAL: Provides access to the underlying in-game product item instance.
/// </summary>
internal S1Product.ProductItemInstance S1ProductInstance =>
CrossType.As<S1Product.ProductItemInstance>(S1ItemInstance);

/// <summary>
/// INTERNAL: Creates a product instance from the in-game product instance.
/// Represents an instance of a product, derived from a specific in-game product item instance,
/// with additional properties for packaging, quality, and product definition.
/// </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.
/// Indicates whether the product instance has applied packaging.
/// </summary>
public bool IsPackaged =>
S1ProductInstance.AppliedPackaging;
public bool IsPackaged => S1ProductInstance.AppliedPackaging;

/// <summary>
/// The type of packaging applied to this product.
/// Provides access to the packaging information applied to the product,
/// represented as a specific packaging definition instance.
/// </summary>
public PackagingDefinition AppliedPackaging =>
new PackagingDefinition(S1ProductInstance.AppliedPackaging);

/// <summary>
/// Represents the quality level of the product instance.
/// </summary>
/// <remarks>
/// Quality levels provide a measure of the product's grading, ranging from "Trash" to "Heavenly".
/// </remarks>
public Quality Quality => S1ProductInstance.Quality.ToAPI();

/// <summary>
/// Gets the definition of the product associated with this instance.
/// </summary>
public ProductDefinition Definition => new ProductDefinition(S1ProductInstance.Definition);

Check warning on line 60 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 60 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 60 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 60 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.

/// <summary>
/// Gets the list of properties associated with the product definition.
/// </summary>
/// <remarks>
/// This property provides an unmodifiable list of properties associated
/// with the underlying product definition. Each property represents
/// a specific characteristic or behavior of the corresponding product.
/// </remarks>
public IReadOnlyList<S1Properties.Property> Properties => Definition.Properties;
}
}
Loading
Loading