From b20a1663afbc155773852c90898db4b9df16b9fa Mon Sep 17 00:00:00 2001 From: SkyeKoi <120770479+UnusualBacon465@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:14:38 -0400 Subject: [PATCH 1/5] seed api commit --- Growing/PlantInstance.cs | 77 ++++++++++++++++++++ Growing/SeedCreator.cs | 57 +++++++++++++++ Growing/SeedDefinition.cs | 54 ++++++++++++++ Growing/SeedInstance.cs | 55 +++++++++++++++ Items/ItemCategory.cs | 70 ++++++++++++++++++ Items/ItemDefinition.cs | 144 ++++++++++++++++++++++++++++++++++++++ Items/ItemInstance.cs | 52 ++++++++++++++ Items/ItemManager.cs | 42 +++++++++++ Items/ItemSlotInstance.cs | 70 ++++++++++++++++++ 9 files changed, 621 insertions(+) create mode 100644 Growing/PlantInstance.cs create mode 100644 Growing/SeedCreator.cs create mode 100644 Growing/SeedDefinition.cs create mode 100644 Growing/SeedInstance.cs create mode 100644 Items/ItemCategory.cs create mode 100644 Items/ItemDefinition.cs create mode 100644 Items/ItemInstance.cs create mode 100644 Items/ItemManager.cs create mode 100644 Items/ItemSlotInstance.cs diff --git a/Growing/PlantInstance.cs b/Growing/PlantInstance.cs new file mode 100644 index 00000000..8bcfe5b6 --- /dev/null +++ b/Growing/PlantInstance.cs @@ -0,0 +1,77 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +#endif + +using S1API.Internal.Utils; +using S1API.Items; +using UnityEngine; + +namespace S1API.Growing +{ + /// + /// Represents an instance of a growing plant in the world. + /// + public class PlantInstance + { + /// + /// INTERNAL: The in-game Plant object. + /// + internal readonly S1Growing.Plant S1Plant; + + /// + /// INTERNAL: Create a wrapper around an existing Plant. + /// + /// The in-game Plant to wrap. + internal PlantInstance(S1Growing.Plant plant) + { + S1Plant = plant; + } + + /// + /// The current growth stage as a float from 0.0 to 1.0. + /// + public float NormalizedGrowth => + S1Plant.NormalizedGrowthProgress; + + /// + /// Whether the plant is fully grown. + /// + public bool IsFullyGrown => + S1Plant.IsFullyGrown; + + /// + /// The SeedDefinition that this plant originated from. + /// + public SeedDefinition SeedDefinition => + new SeedDefinition(S1Plant.SeedDefinition); + + /// + /// The quality level of this plant. + /// + public float Quality => + S1Plant.QualityLevel; + + /// + /// The yield level (amount) of this plant. + /// + public float Yield => + S1Plant.YieldLevel; + + /// + /// The GameObject of the plant. + /// + public GameObject GameObject => + S1Plant.gameObject; + + /// + /// Destroys this plant in-game. + /// + /// Whether to drop trash scraps. + public void Destroy(bool dropScraps = false) + { + S1Plant.Destroy(dropScraps); + } + } +} diff --git a/Growing/SeedCreator.cs b/Growing/SeedCreator.cs new file mode 100644 index 00000000..8729a58f --- /dev/null +++ b/Growing/SeedCreator.cs @@ -0,0 +1,57 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +using S1Registry = Il2CppScheduleOne.Registry; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +using S1ItemFramework = ScheduleOne.ItemFramework; +using S1Registry = ScheduleOne.Registry; +#endif + +using UnityEngine; +using System.Linq; + + +namespace S1API.Growing +{ + /// + /// The seed Creator for custom seeds to be added. + /// + public static class SeedCreator + { + public static SeedDefinition CreateSeed( + string id, + string name, + string description, + int stackLimit = 10, + GameObject functionSeedPrefab = null, + GameObject plantPrefab = null, + Sprite icon = null) + { + S1Growing.SeedDefinition seed = ScriptableObject.CreateInstance(); + + seed.ID = id; + seed.Name = name; + seed.Description = description; + seed.StackLimit = stackLimit; + seed.Category = S1ItemFramework.EItemCategory.Growing; + + // if (icon != null) + // { + // seed.Icon = icon; + // } + // commented out for more test later. + + if (functionSeedPrefab != null) + seed.FunctionSeedPrefab = functionSeedPrefab.GetComponent(); + + if (plantPrefab != null) + seed.PlantPrefab = plantPrefab.GetComponent(); + + S1Registry.Instance.AddToRegistry(seed); + + return new SeedDefinition(seed); + } + + } +} \ No newline at end of file diff --git a/Growing/SeedDefinition.cs b/Growing/SeedDefinition.cs new file mode 100644 index 00000000..745a8e17 --- /dev/null +++ b/Growing/SeedDefinition.cs @@ -0,0 +1,54 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +#endif + +using S1API.Internal.Utils; +using S1API.Items; + +namespace S1API.Growing +{ + /// + /// Represents the definition of a Seed item (what you buy in shops). + /// + public class SeedDefinition : ItemDefinition + { + /// + /// INTERNAL: Stored reference to the SeedDefinition. + /// + internal S1Growing.SeedDefinition S1SeedDefinition => + CrossType.As(S1ItemDefinition); + + /// + /// INTERNAL: Create a new wrapper around an existing SeedDefinition. + /// + /// The in-game SeedDefinition to wrap. + internal SeedDefinition(S1Growing.SeedDefinition definition) : base(definition) { } + + /// + /// The prefab that is spawned when planting this seed. + /// + public UnityEngine.GameObject FunctionalSeedPrefab => + S1SeedDefinition.FunctionSeedPrefab?.gameObject; + + /// + /// The plant prefab this seed grows into. + /// + public UnityEngine.GameObject PlantPrefab => + S1SeedDefinition.PlantPrefab?.gameObject; + + /// + /// Creates an instance of this seed in the world (FunctionalSeed prefab). + /// + public UnityEngine.GameObject CreateSeedInstance() + { + if (S1SeedDefinition.FunctionSeedPrefab != null) + return UnityEngine.Object.Instantiate(S1SeedDefinition.FunctionSeedPrefab).gameObject; + + throw new System.NullReferenceException("No FunctionalSeedPrefab assigned to this SeedDefinition!"); + } + + + } +} \ No newline at end of file diff --git a/Growing/SeedInstance.cs b/Growing/SeedInstance.cs new file mode 100644 index 00000000..4f0f8b73 --- /dev/null +++ b/Growing/SeedInstance.cs @@ -0,0 +1,55 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +#endif + +using UnityEngine; +using S1API.Internal.Utils; + +namespace S1API.Growing +{ + /// + /// Represents an instance of a functional seed in the world. + /// (Not just the definition — this is the physical object you interact with.) + /// + public class SeedInstance + { + /// + /// INTERNAL: Reference to the in-game FunctionalSeed object. + /// + internal readonly S1Growing.FunctionalSeed S1FunctionalSeed; + + /// + /// INTERNAL: Creates a wrapper around the existing FunctionalSeed. + /// + /// The FunctionalSeed object to wrap. + internal SeedInstance(S1Growing.FunctionalSeed functionalSeed) + { + S1FunctionalSeed = functionalSeed; + } + + /// + /// The underlying GameObject of this seed. + /// + public GameObject GameObject => + S1FunctionalSeed.gameObject; + + /// + /// Whether the seed currently has exited its vial. + /// + public bool HasExitedVial { get; private set; } = false; + + /// + /// Force the seed to exit the vial manually. + /// + public void ForceExitVial() + { + if (S1FunctionalSeed.Vial != null) + { + S1FunctionalSeed.TriggerExit(S1FunctionalSeed.Vial.GetComponent()); + HasExitedVial = true; + } + } + } +} \ No newline at end of file diff --git a/Items/ItemCategory.cs b/Items/ItemCategory.cs new file mode 100644 index 00000000..a4e88df8 --- /dev/null +++ b/Items/ItemCategory.cs @@ -0,0 +1,70 @@ +namespace S1API.Items +{ + /// + /// A list of item categories available in-game. + /// + public enum ItemCategory + { + /// + /// Represents items such as Cocaine, Weed, etc. + /// Oddly, SpeedGrow is in this category as of (v0.3.4f8). + /// + Product, + + /// + /// Represents items such as Baggies, Bricks, Jars, etc. + /// + Packaging, + + /// + /// Represents items such as Soil, Fertilizer, Pots, etc. + /// + Growing, + + /// + /// Represents equipment tools such as the clippers. + /// Oddly, trash bags is in this category as of (v0.3.4f8). + /// + Tools, + + /// + /// Represents items such as TV, Trash Can, Bed, etc. + /// + Furniture, + + /// + /// Represents items such as Floor Lamps, Halogen Lights, etc. + /// + Lighting, + + /// + /// Represents cash-based items. + /// + Cash, + + /// + /// Represents items such as Cuke, Energy Drink, etc. + /// + Consumable, + + /// + /// Represents items such as Drying Rack, Brick Press, Mixing Station, etc. + /// + Equipment, + + /// + /// Represents items such as Acid, Banana, Chili, etc. + /// + Ingredient, + + /// + /// Represents items such as GoldBar, WallClock, WoodSign, etc. + /// + Decoration, + + /// + /// Represents clothing items. + /// + Clothing + } +} \ No newline at end of file diff --git a/Items/ItemDefinition.cs b/Items/ItemDefinition.cs new file mode 100644 index 00000000..0c14e2b1 --- /dev/null +++ b/Items/ItemDefinition.cs @@ -0,0 +1,144 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +#elif (MONOMELON || MONOBEPINEX) +using S1ItemFramework = ScheduleOne.ItemFramework; +#endif + +using UnityEngine; +using S1API.Internal.Abstraction; + +namespace S1API.Items +{ + /// + /// Represents an item definition in-game. + /// Use this class to read and create new item definitions dynamically. + /// + public class ItemDefinition : IGUIDReference + { + /// + /// INTERNAL: A reference to the native game item definition. + /// + internal S1ItemFramework.ItemDefinition S1ItemDefinition { get; } + + /// + /// INTERNAL: Wraps an existing native item definition. + /// + internal ItemDefinition(S1ItemFramework.ItemDefinition definition) + { + S1ItemDefinition = definition; + } + + /// + /// The unique ID of this item. + /// + public string ID + { + get => S1ItemDefinition.ID; + set => S1ItemDefinition.ID = value; + } + + /// + /// The display name for this item. + /// + public string Name + { + get => S1ItemDefinition.Name; + set => S1ItemDefinition.Name = value; + } + + /// + /// A short description for this item. + /// + public string Description + { + get => S1ItemDefinition.Description; + set => S1ItemDefinition.Description = value; + } + + /// + /// Stack limit for this item (max quantity per slot). + /// + public int StackLimit + { + get => S1ItemDefinition.StackLimit; + set => S1ItemDefinition.StackLimit = value; + } + + /// + /// The category for inventory sorting. + /// + public ItemCategory Category + { + get => (ItemCategory)S1ItemDefinition.Category; + set => S1ItemDefinition.Category = (S1ItemFramework.EItemCategory)value; + } + + /// + /// The icon for this item. + /// + public Sprite Icon + { + get => S1ItemDefinition.Icon; + set => S1ItemDefinition.Icon = value; + } + + /// + /// Whether this item is available in the demo version of the game. + /// + public bool AvailableInDemo + { + get => S1ItemDefinition.AvailableInDemo; + set => S1ItemDefinition.AvailableInDemo = value; + } + + /// + /// Legal status of the item (e.g., illegal drugs). + /// + public S1ItemFramework.ELegalStatus LegalStatus + { + get => S1ItemDefinition.legalStatus; + set => S1ItemDefinition.legalStatus = value; + } + + /// + /// The color of the label shown in UI. + /// + public Color LabelDisplayColor + { + get => S1ItemDefinition.LabelDisplayColor; + set => S1ItemDefinition.LabelDisplayColor = value; + } + + /// + /// Any keywords used to filter/search this item. + /// + public string[] Keywords + { + get => S1ItemDefinition.Keywords; + set => S1ItemDefinition.Keywords = value; + } + + /// + /// Creates a new item instance with the specified quantity. + /// + public virtual ItemInstance CreateInstance(int quantity = 1) + { + var inst = S1ItemDefinition.GetDefaultInstance(quantity); + return new ItemInstance(inst); + } + + public string GUID => ID; + + public override bool Equals(object? obj) => + obj is ItemDefinition other && S1ItemDefinition == other.S1ItemDefinition; + + public override int GetHashCode() => + S1ItemDefinition?.GetHashCode() ?? 0; + + public static bool operator ==(ItemDefinition? a, ItemDefinition? b) => + ReferenceEquals(a, b) || (a is not null && b is not null && a.S1ItemDefinition == b.S1ItemDefinition); + + public static bool operator !=(ItemDefinition? a, ItemDefinition? b) => + !(a == b); + } +} diff --git a/Items/ItemInstance.cs b/Items/ItemInstance.cs new file mode 100644 index 00000000..df388f4e --- /dev/null +++ b/Items/ItemInstance.cs @@ -0,0 +1,52 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +#elif (MONOMELON || MONOBEPINEX) +using S1ItemFramework = ScheduleOne.ItemFramework; +#endif + +using S1API.Items; +using S1API.Internal.Utils; + +namespace S1API.Items +{ + /// + /// Represents an item instance in the game world (physical item you own). + /// + public class ItemInstance + { + /// + /// INTERNAL: Reference to the in-game item instance. + /// + internal readonly S1ItemFramework.ItemInstance S1ItemInstance; + + /// + /// INTERNAL: Creates an ItemInstance wrapper. + /// + /// In-game item instance + internal ItemInstance(S1ItemFramework.ItemInstance itemInstance) => + S1ItemInstance = itemInstance; + + // ====== Properties ====== + + /// + /// The definition (template) this instance was created from. + /// + public ItemDefinition Definition => + new ItemDefinition(S1ItemInstance.Definition); + + /// + /// Current quantity of this item (stacks). + /// + public int Quantity + { + get => S1ItemInstance.Quantity; + set => S1ItemInstance.SetQuantity(value); + } + + /// + /// Whether this instance is stackable (based on StackLimit). + /// + public bool IsStackable => + Definition.StackLimit > 1; + } +} diff --git a/Items/ItemManager.cs b/Items/ItemManager.cs new file mode 100644 index 00000000..e886c6df --- /dev/null +++ b/Items/ItemManager.cs @@ -0,0 +1,42 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1 = Il2CppScheduleOne; +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +using S1Product = Il2CppScheduleOne.Product; +#elif (MONOMELON || MONOBEPINEX) +using S1 = ScheduleOne; +using S1ItemFramework = ScheduleOne.ItemFramework; +using S1Product = ScheduleOne.Product; +#endif + +using S1API.Internal.Utils; +using S1API.Money; +using S1API.Products; + +namespace S1API.Items +{ + /// + /// Provides access to managing items across the game. + /// + public static class ItemManager + { + /// + /// Gets the definition of an item by its ID. + /// + /// The ID of the item. + /// An instance of the item definition. + public static ItemDefinition GetItemDefinition(string itemID) + { + S1ItemFramework.ItemDefinition itemDefinition = S1.Registry.GetItem(itemID); + + if (CrossType.Is(itemDefinition, + out S1Product.ProductDefinition productDefinition)) + return new ProductDefinition(productDefinition); + + if (CrossType.Is(itemDefinition, + out S1ItemFramework.CashDefinition cashDefinition)) + return new CashDefinition(cashDefinition); + + return new ItemDefinition(itemDefinition); + } + } +} diff --git a/Items/ItemSlotInstance.cs b/Items/ItemSlotInstance.cs new file mode 100644 index 00000000..ad51429d --- /dev/null +++ b/Items/ItemSlotInstance.cs @@ -0,0 +1,70 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +using S1Product = Il2CppScheduleOne.Product; +#elif (MONOMELON || MONOBEPINEX) +using S1ItemFramework = ScheduleOne.ItemFramework; +using S1Product = ScheduleOne.Product; +#endif + +using S1API.Internal.Utils; +using S1API.Money; +using S1API.Products; + +namespace S1API.Items +{ + /// + /// Represents an item slot within the game. + /// These are present within storage, the hot bar, etc. + /// + public class ItemSlotInstance + { + /// + /// INTERNAL: The reference to the item slot in the game. + /// + internal readonly S1ItemFramework.ItemSlot S1ItemSlot; + + /// + /// Creates an item slot instance from the in game slot. + /// + /// + internal ItemSlotInstance(S1ItemFramework.ItemSlot itemSlot) => + S1ItemSlot = itemSlot; + + /// + /// The quantity of item in this slot. + /// + public int Quantity => + S1ItemSlot.Quantity; + + /// + /// The item instance the slot contains. + /// + public ItemInstance? ItemInstance + { + get + { + if (CrossType.Is(S1ItemSlot.ItemInstance, + out S1Product.ProductItemInstance productItemInstance)) + return new ProductInstance(productItemInstance); + + if (CrossType.Is(S1ItemSlot.ItemInstance, + out S1ItemFramework.CashInstance cashInstance)) + return new CashInstance(cashInstance); + + if (CrossType.Is(S1ItemSlot.ItemInstance, + out S1ItemFramework.ItemInstance itemInstance)) + return new ItemInstance(itemInstance); + + return null; + } + } + + /// + /// Adds a quantity to the item in this slot. + /// NOTE: Negative numbers are supported and allowed. + /// + /// + public void AddQuantity(int amount) => + S1ItemSlot.ChangeQuantity(amount); + } +} From 2f574b9ed58337d3a0646233b1ae61708642b9e0 Mon Sep 17 00:00:00 2001 From: SkyeKoi <120770479+UnusualBacon465@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:57:33 -0400 Subject: [PATCH 2/5] added wrapper, made one like private. --- Growing/SeedInstance.cs | 2 +- Items/ItemDefinition.cs | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Growing/SeedInstance.cs b/Growing/SeedInstance.cs index 4f0f8b73..97bafe45 100644 --- a/Growing/SeedInstance.cs +++ b/Growing/SeedInstance.cs @@ -32,7 +32,7 @@ internal SeedInstance(S1Growing.FunctionalSeed functionalSeed) /// /// The underlying GameObject of this seed. /// - public GameObject GameObject => + private GameObject GameObject => S1FunctionalSeed.gameObject; /// diff --git a/Items/ItemDefinition.cs b/Items/ItemDefinition.cs index 0c14e2b1..c2f3b4db 100644 --- a/Items/ItemDefinition.cs +++ b/Items/ItemDefinition.cs @@ -94,12 +94,13 @@ public bool AvailableInDemo /// /// Legal status of the item (e.g., illegal drugs). /// - public S1ItemFramework.ELegalStatus LegalStatus + public LegalStatus LegalStatus { - get => S1ItemDefinition.legalStatus; - set => S1ItemDefinition.legalStatus = value; + get => (LegalStatus)S1ItemDefinition.legalStatus; + set => S1ItemDefinition.legalStatus = (S1ItemFramework.ELegalStatus)value; } + /// /// The color of the label shown in UI. /// @@ -127,6 +128,7 @@ public virtual ItemInstance CreateInstance(int quantity = 1) return new ItemInstance(inst); } + public string GUID => ID; public override bool Equals(object? obj) => @@ -141,4 +143,14 @@ public override int GetHashCode() => public static bool operator !=(ItemDefinition? a, ItemDefinition? b) => !(a == b); } + + /// + /// Represents the legal status of an item (e.g., legal or illegal). + /// + public enum LegalStatus + { + Legal, + Illegal, + // More if needed + } } From 36801f6cd91a9264da5c4c343c9cc8c5587aecd7 Mon Sep 17 00:00:00 2001 From: SkyeKoi <120770479+UnusualBacon465@users.noreply.github.com> Date: Mon, 28 Apr 2025 23:09:33 -0400 Subject: [PATCH 3/5] reupload of items --- S1API/Items/ItemDefinition.cs | 160 ++++++++++++++++++++------------ S1API/Items/ItemInstance.cs | 33 +++++-- S1API/Items/ItemManager.cs | 4 +- S1API/Items/ItemSlotInstance.cs | 20 ++-- 4 files changed, 136 insertions(+), 81 deletions(-) diff --git a/S1API/Items/ItemDefinition.cs b/S1API/Items/ItemDefinition.cs index 2ac08b66..c2f3b4db 100644 --- a/S1API/Items/ItemDefinition.cs +++ b/S1API/Items/ItemDefinition.cs @@ -1,118 +1,156 @@ #if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif +using UnityEngine; using S1API.Internal.Abstraction; namespace S1API.Items { /// /// Represents an item definition in-game. - /// NOTE: A definition is "what" the item is. For example, "This is a `Soda`". - /// Any instanced items in the game will be a instead. + /// Use this class to read and create new item definitions dynamically. /// public class ItemDefinition : IGUIDReference { /// - /// INTERNAL: A reference to the item definition in the game. + /// INTERNAL: A reference to the native game item definition. /// - internal readonly S1ItemFramework.ItemDefinition S1ItemDefinition; + internal S1ItemFramework.ItemDefinition S1ItemDefinition { get; } /// - /// Creates a new item definition from the game item definition instance. + /// INTERNAL: Wraps an existing native item definition. /// - /// - internal ItemDefinition(S1ItemFramework.ItemDefinition s1ItemDefinition) => - S1ItemDefinition = s1ItemDefinition; + internal ItemDefinition(S1ItemFramework.ItemDefinition definition) + { + S1ItemDefinition = definition; + } /// - /// INTERNAL: Gets an item definition from a GUID. + /// The unique ID of this item. /// - /// The GUID to look for - /// The applicable item definition, if found. - internal static ItemDefinition GetFromGUID(string guid) => - ItemManager.GetItemDefinition(guid); + public string ID + { + get => S1ItemDefinition.ID; + set => S1ItemDefinition.ID = value; + } /// - /// Performs an equals check on the game item definition instance. + /// The display name for this item. /// - /// The item definition you want to compare against. - /// Whether the item definitions are the same or not. - public override bool Equals(object? obj) => - obj is ItemDefinition other && S1ItemDefinition == other.S1ItemDefinition; + public string Name + { + get => S1ItemDefinition.Name; + set => S1ItemDefinition.Name = value; + } /// - /// Snags the hash code from the game instance versus this instance. + /// A short description for this item. /// - /// The game intance hash code - public override int GetHashCode() => - S1ItemDefinition?.GetHashCode() ?? 0; + public string Description + { + get => S1ItemDefinition.Description; + set => S1ItemDefinition.Description = value; + } /// - /// Performs an == check on the game item definition instance. + /// Stack limit for this item (max quantity per slot). /// - /// The first item definition to compare. - /// The second item definition to compare. - /// Whether the item definitions are the same or not. - public static bool operator ==(ItemDefinition? left, ItemDefinition? right) + public int StackLimit { - if (ReferenceEquals(left, right)) return true; - return left?.S1ItemDefinition == right?.S1ItemDefinition; + get => S1ItemDefinition.StackLimit; + set => S1ItemDefinition.StackLimit = value; } /// - /// Performs an != check on the game item definition instance. + /// The category for inventory sorting. /// - /// The first item definition to compare. - /// The second item definition to compare. - /// Whether the item definitions are different or not. - public static bool operator !=(ItemDefinition left, ItemDefinition right) => - !(left == right); + public ItemCategory Category + { + get => (ItemCategory)S1ItemDefinition.Category; + set => S1ItemDefinition.Category = (S1ItemFramework.EItemCategory)value; + } /// - /// The unique identifier assigned to this item definition. + /// The icon for this item. /// - public virtual string GUID => - S1ItemDefinition.ID; + public Sprite Icon + { + get => S1ItemDefinition.Icon; + set => S1ItemDefinition.Icon = value; + } /// - /// The unique identifier assigned to this item definition. + /// Whether this item is available in the demo version of the game. /// - public string ID => - S1ItemDefinition.ID; + public bool AvailableInDemo + { + get => S1ItemDefinition.AvailableInDemo; + set => S1ItemDefinition.AvailableInDemo = value; + } /// - /// The display name for this item. + /// Legal status of the item (e.g., illegal drugs). /// - public string Name => - S1ItemDefinition.Name; + public LegalStatus LegalStatus + { + get => (LegalStatus)S1ItemDefinition.legalStatus; + set => S1ItemDefinition.legalStatus = (S1ItemFramework.ELegalStatus)value; + } - /// - /// The description used for this item. - /// - public string Description => - S1ItemDefinition.Description; /// - /// The category this item is assigned to. + /// The color of the label shown in UI. /// - public ItemCategory Category => - (ItemCategory)S1ItemDefinition.Category; + public Color LabelDisplayColor + { + get => S1ItemDefinition.LabelDisplayColor; + set => S1ItemDefinition.LabelDisplayColor = value; + } /// - /// The stack limit for this item. + /// Any keywords used to filter/search this item. /// - public int StackLimit => - S1ItemDefinition.StackLimit; + public string[] Keywords + { + get => S1ItemDefinition.Keywords; + set => S1ItemDefinition.Keywords = value; + } /// - /// Creates an instance of this item from the definition. + /// Creates a new item instance with the specified quantity. /// - /// How many of the item the instance will have. - /// A new item instance within the game. - public virtual ItemInstance CreateInstance(int quantity = 1) => - new ItemInstance(S1ItemDefinition.GetDefaultInstance(quantity)); + public virtual ItemInstance CreateInstance(int quantity = 1) + { + var inst = S1ItemDefinition.GetDefaultInstance(quantity); + return new ItemInstance(inst); + } + + + public string GUID => ID; + + public override bool Equals(object? obj) => + obj is ItemDefinition other && S1ItemDefinition == other.S1ItemDefinition; + + public override int GetHashCode() => + S1ItemDefinition?.GetHashCode() ?? 0; + + public static bool operator ==(ItemDefinition? a, ItemDefinition? b) => + ReferenceEquals(a, b) || (a is not null && b is not null && a.S1ItemDefinition == b.S1ItemDefinition); + + public static bool operator !=(ItemDefinition? a, ItemDefinition? b) => + !(a == b); + } + + /// + /// Represents the legal status of an item (e.g., legal or illegal). + /// + public enum LegalStatus + { + Legal, + Illegal, + // More if needed } } diff --git a/S1API/Items/ItemInstance.cs b/S1API/Items/ItemInstance.cs index 541b35d8..df388f4e 100644 --- a/S1API/Items/ItemInstance.cs +++ b/S1API/Items/ItemInstance.cs @@ -1,35 +1,52 @@ #if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif +using S1API.Items; +using S1API.Internal.Utils; namespace S1API.Items { /// - /// Represents an item instance in the game. - /// NOTE: A instance is the item existing in the game world. For example, "I have five sodas in my hand.". - /// The definition for items in the game will be a instead. + /// Represents an item instance in the game world (physical item you own). /// public class ItemInstance { /// - /// INTERNAL: The reference to the instance of this item. + /// INTERNAL: Reference to the in-game item instance. /// internal readonly S1ItemFramework.ItemInstance S1ItemInstance; /// - /// INTERNAL: Creates an item instance + /// INTERNAL: Creates an ItemInstance wrapper. /// - /// The instance of the item instance in-game. + /// In-game item instance internal ItemInstance(S1ItemFramework.ItemInstance itemInstance) => S1ItemInstance = itemInstance; + // ====== Properties ====== + /// - /// The item definition of this item. + /// The definition (template) this instance was created from. /// public ItemDefinition Definition => new ItemDefinition(S1ItemInstance.Definition); + + /// + /// Current quantity of this item (stacks). + /// + public int Quantity + { + get => S1ItemInstance.Quantity; + set => S1ItemInstance.SetQuantity(value); + } + + /// + /// Whether this instance is stackable (based on StackLimit). + /// + public bool IsStackable => + Definition.StackLimit > 1; } } diff --git a/S1API/Items/ItemManager.cs b/S1API/Items/ItemManager.cs index 35960b33..e886c6df 100644 --- a/S1API/Items/ItemManager.cs +++ b/S1API/Items/ItemManager.cs @@ -2,7 +2,7 @@ using S1 = Il2CppScheduleOne; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) +#elif (MONOMELON || MONOBEPINEX) using S1 = ScheduleOne; using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; @@ -35,7 +35,7 @@ public static ItemDefinition GetItemDefinition(string itemID) if (CrossType.Is(itemDefinition, out S1ItemFramework.CashDefinition cashDefinition)) return new CashDefinition(cashDefinition); - + return new ItemDefinition(itemDefinition); } } diff --git a/S1API/Items/ItemSlotInstance.cs b/S1API/Items/ItemSlotInstance.cs index 6ca6f24e..ad51429d 100644 --- a/S1API/Items/ItemSlotInstance.cs +++ b/S1API/Items/ItemSlotInstance.cs @@ -1,7 +1,7 @@ #if (IL2CPPMELON || IL2CPPBEPINEX) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) +#elif (MONOMELON || MONOBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; #endif @@ -22,18 +22,18 @@ public class ItemSlotInstance /// INTERNAL: The reference to the item slot in the game. /// internal readonly S1ItemFramework.ItemSlot S1ItemSlot; - + /// /// Creates an item slot instance from the in game slot. /// /// - internal ItemSlotInstance(S1ItemFramework.ItemSlot itemSlot) => + internal ItemSlotInstance(S1ItemFramework.ItemSlot itemSlot) => S1ItemSlot = itemSlot; - + /// /// The quantity of item in this slot. /// - public int Quantity => + public int Quantity => S1ItemSlot.Quantity; /// @@ -46,11 +46,11 @@ public ItemInstance? ItemInstance if (CrossType.Is(S1ItemSlot.ItemInstance, out S1Product.ProductItemInstance productItemInstance)) return new ProductInstance(productItemInstance); - + if (CrossType.Is(S1ItemSlot.ItemInstance, out S1ItemFramework.CashInstance cashInstance)) return new CashInstance(cashInstance); - + if (CrossType.Is(S1ItemSlot.ItemInstance, out S1ItemFramework.ItemInstance itemInstance)) return new ItemInstance(itemInstance); @@ -58,13 +58,13 @@ public ItemInstance? ItemInstance return null; } } - + /// /// Adds a quantity to the item in this slot. /// NOTE: Negative numbers are supported and allowed. /// /// - public void AddQuantity(int amount) => - S1ItemSlot.ChangeQuantity(amount); + public void AddQuantity(int amount) => + S1ItemSlot.ChangeQuantity(amount); } } From 309e4f93462537b9ebac472da7b5250e6735eadd Mon Sep 17 00:00:00 2001 From: SkyeKoi <120770479+UnusualBacon465@users.noreply.github.com> Date: Mon, 28 Apr 2025 23:09:56 -0400 Subject: [PATCH 4/5] Add files via upload --- S1API/Growing/PlantInstance.cs | 77 +++++++++++++++++++++++++++++++++ S1API/Growing/SeedCreator.cs | 57 ++++++++++++++++++++++++ S1API/Growing/SeedDefinition.cs | 54 +++++++++++++++++++++++ S1API/Growing/SeedInstance.cs | 55 +++++++++++++++++++++++ 4 files changed, 243 insertions(+) create mode 100644 S1API/Growing/PlantInstance.cs create mode 100644 S1API/Growing/SeedCreator.cs create mode 100644 S1API/Growing/SeedDefinition.cs create mode 100644 S1API/Growing/SeedInstance.cs diff --git a/S1API/Growing/PlantInstance.cs b/S1API/Growing/PlantInstance.cs new file mode 100644 index 00000000..9ef63956 --- /dev/null +++ b/S1API/Growing/PlantInstance.cs @@ -0,0 +1,77 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +#endif + +using S1API.Internal.Utils; +using S1API.Items; +using UnityEngine; + +namespace S1API.Growing +{ + /// + /// Represents an instance of a growing plant in the world. + /// + public class PlantInstance + { + /// + /// INTERNAL: The in-game Plant object. + /// + internal readonly S1Growing.Plant S1Plant; + + /// + /// INTERNAL: Create a wrapper around an existing Plant. + /// + /// The in-game Plant to wrap. + internal PlantInstance(S1Growing.Plant plant) + { + S1Plant = plant; + } + + /// + /// The current growth stage as a float from 0.0 to 1.0. + /// + public float NormalizedGrowth => + S1Plant.NormalizedGrowthProgress; + + /// + /// Whether the plant is fully grown. + /// + public bool IsFullyGrown => + S1Plant.IsFullyGrown; + + /// + /// The SeedDefinition that this plant originated from. + /// + public SeedDefinition SeedDefinition => + new SeedDefinition(S1Plant.SeedDefinition); + + /// + /// The quality level of this plant. + /// + public float Quality => + S1Plant.QualityLevel; + + /// + /// The yield level (amount) of this plant. + /// + public float Yield => + S1Plant.YieldLevel; + + /// + /// The GameObject of the plant. + /// + private GameObject GameObject => + S1Plant.gameObject; + + /// + /// Destroys this plant in-game. + /// + /// Whether to drop trash scraps. + public void Destroy(bool dropScraps = false) + { + S1Plant.Destroy(dropScraps); + } + } +} diff --git a/S1API/Growing/SeedCreator.cs b/S1API/Growing/SeedCreator.cs new file mode 100644 index 00000000..8729a58f --- /dev/null +++ b/S1API/Growing/SeedCreator.cs @@ -0,0 +1,57 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +using S1ItemFramework = Il2CppScheduleOne.ItemFramework; +using S1Registry = Il2CppScheduleOne.Registry; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +using S1ItemFramework = ScheduleOne.ItemFramework; +using S1Registry = ScheduleOne.Registry; +#endif + +using UnityEngine; +using System.Linq; + + +namespace S1API.Growing +{ + /// + /// The seed Creator for custom seeds to be added. + /// + public static class SeedCreator + { + public static SeedDefinition CreateSeed( + string id, + string name, + string description, + int stackLimit = 10, + GameObject functionSeedPrefab = null, + GameObject plantPrefab = null, + Sprite icon = null) + { + S1Growing.SeedDefinition seed = ScriptableObject.CreateInstance(); + + seed.ID = id; + seed.Name = name; + seed.Description = description; + seed.StackLimit = stackLimit; + seed.Category = S1ItemFramework.EItemCategory.Growing; + + // if (icon != null) + // { + // seed.Icon = icon; + // } + // commented out for more test later. + + if (functionSeedPrefab != null) + seed.FunctionSeedPrefab = functionSeedPrefab.GetComponent(); + + if (plantPrefab != null) + seed.PlantPrefab = plantPrefab.GetComponent(); + + S1Registry.Instance.AddToRegistry(seed); + + return new SeedDefinition(seed); + } + + } +} \ No newline at end of file diff --git a/S1API/Growing/SeedDefinition.cs b/S1API/Growing/SeedDefinition.cs new file mode 100644 index 00000000..745a8e17 --- /dev/null +++ b/S1API/Growing/SeedDefinition.cs @@ -0,0 +1,54 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +#endif + +using S1API.Internal.Utils; +using S1API.Items; + +namespace S1API.Growing +{ + /// + /// Represents the definition of a Seed item (what you buy in shops). + /// + public class SeedDefinition : ItemDefinition + { + /// + /// INTERNAL: Stored reference to the SeedDefinition. + /// + internal S1Growing.SeedDefinition S1SeedDefinition => + CrossType.As(S1ItemDefinition); + + /// + /// INTERNAL: Create a new wrapper around an existing SeedDefinition. + /// + /// The in-game SeedDefinition to wrap. + internal SeedDefinition(S1Growing.SeedDefinition definition) : base(definition) { } + + /// + /// The prefab that is spawned when planting this seed. + /// + public UnityEngine.GameObject FunctionalSeedPrefab => + S1SeedDefinition.FunctionSeedPrefab?.gameObject; + + /// + /// The plant prefab this seed grows into. + /// + public UnityEngine.GameObject PlantPrefab => + S1SeedDefinition.PlantPrefab?.gameObject; + + /// + /// Creates an instance of this seed in the world (FunctionalSeed prefab). + /// + public UnityEngine.GameObject CreateSeedInstance() + { + if (S1SeedDefinition.FunctionSeedPrefab != null) + return UnityEngine.Object.Instantiate(S1SeedDefinition.FunctionSeedPrefab).gameObject; + + throw new System.NullReferenceException("No FunctionalSeedPrefab assigned to this SeedDefinition!"); + } + + + } +} \ No newline at end of file diff --git a/S1API/Growing/SeedInstance.cs b/S1API/Growing/SeedInstance.cs new file mode 100644 index 00000000..97bafe45 --- /dev/null +++ b/S1API/Growing/SeedInstance.cs @@ -0,0 +1,55 @@ +#if (IL2CPPMELON || IL2CPPBEPINEX) +using S1Growing = Il2CppScheduleOne.Growing; +#elif (MONOMELON || MONOBEPINEX) +using S1Growing = ScheduleOne.Growing; +#endif + +using UnityEngine; +using S1API.Internal.Utils; + +namespace S1API.Growing +{ + /// + /// Represents an instance of a functional seed in the world. + /// (Not just the definition — this is the physical object you interact with.) + /// + public class SeedInstance + { + /// + /// INTERNAL: Reference to the in-game FunctionalSeed object. + /// + internal readonly S1Growing.FunctionalSeed S1FunctionalSeed; + + /// + /// INTERNAL: Creates a wrapper around the existing FunctionalSeed. + /// + /// The FunctionalSeed object to wrap. + internal SeedInstance(S1Growing.FunctionalSeed functionalSeed) + { + S1FunctionalSeed = functionalSeed; + } + + /// + /// The underlying GameObject of this seed. + /// + private GameObject GameObject => + S1FunctionalSeed.gameObject; + + /// + /// Whether the seed currently has exited its vial. + /// + public bool HasExitedVial { get; private set; } = false; + + /// + /// Force the seed to exit the vial manually. + /// + public void ForceExitVial() + { + if (S1FunctionalSeed.Vial != null) + { + S1FunctionalSeed.TriggerExit(S1FunctionalSeed.Vial.GetComponent()); + HasExitedVial = true; + } + } + } +} \ No newline at end of file From 4d97715862cd902fbb62d7c0c00a52dc893fbb25 Mon Sep 17 00:00:00 2001 From: MaxtorCoder Date: Sun, 4 May 2025 13:47:08 +0200 Subject: [PATCH 5/5] fix: Fix BepInEx IL2CPP build --- S1API/Growing/PlantInstance.cs | 16 +++++++-------- S1API/Growing/SeedCreator.cs | 14 ++++++------- S1API/Growing/SeedDefinition.cs | 21 ++++++++++---------- S1API/Growing/SeedInstance.cs | 8 ++++---- S1API/Items/ItemDefinition.cs | 35 ++++++++++++++++++++++++++------- S1API/Items/ItemInstance.cs | 4 ++-- S1API/Items/ItemManager.cs | 4 ++-- S1API/Items/ItemSlotInstance.cs | 20 +++++++++---------- S1API/S1API.csproj | 4 +++- 9 files changed, 74 insertions(+), 52 deletions(-) diff --git a/S1API/Growing/PlantInstance.cs b/S1API/Growing/PlantInstance.cs index 9ef63956..b706b05d 100644 --- a/S1API/Growing/PlantInstance.cs +++ b/S1API/Growing/PlantInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPPMELON || IL2CPPBEPINEX) +#if (IL2CPPMELON) using S1Growing = Il2CppScheduleOne.Growing; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1Growing = ScheduleOne.Growing; #endif @@ -32,37 +32,37 @@ internal PlantInstance(S1Growing.Plant plant) /// /// The current growth stage as a float from 0.0 to 1.0. /// - public float NormalizedGrowth => + public float NormalizedGrowth => S1Plant.NormalizedGrowthProgress; /// /// Whether the plant is fully grown. /// - public bool IsFullyGrown => + public bool IsFullyGrown => S1Plant.IsFullyGrown; /// /// The SeedDefinition that this plant originated from. /// - public SeedDefinition SeedDefinition => + public SeedDefinition SeedDefinition => new SeedDefinition(S1Plant.SeedDefinition); /// /// The quality level of this plant. /// - public float Quality => + public float Quality => S1Plant.QualityLevel; /// /// The yield level (amount) of this plant. /// - public float Yield => + public float Yield => S1Plant.YieldLevel; /// /// The GameObject of the plant. /// - private GameObject GameObject => + private GameObject GameObject => S1Plant.gameObject; /// diff --git a/S1API/Growing/SeedCreator.cs b/S1API/Growing/SeedCreator.cs index 8729a58f..18b7a556 100644 --- a/S1API/Growing/SeedCreator.cs +++ b/S1API/Growing/SeedCreator.cs @@ -1,16 +1,14 @@ -#if (IL2CPPMELON || IL2CPPBEPINEX) +#if (IL2CPPMELON) using S1Growing = Il2CppScheduleOne.Growing; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Registry = Il2CppScheduleOne.Registry; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1Growing = ScheduleOne.Growing; using S1ItemFramework = ScheduleOne.ItemFramework; using S1Registry = ScheduleOne.Registry; #endif using UnityEngine; -using System.Linq; - namespace S1API.Growing { @@ -24,9 +22,9 @@ public static SeedDefinition CreateSeed( string name, string description, int stackLimit = 10, - GameObject functionSeedPrefab = null, - GameObject plantPrefab = null, - Sprite icon = null) + GameObject? functionSeedPrefab = null, + GameObject? plantPrefab = null, + Sprite? icon = null) { S1Growing.SeedDefinition seed = ScriptableObject.CreateInstance(); @@ -54,4 +52,4 @@ public static SeedDefinition CreateSeed( } } -} \ No newline at end of file +} diff --git a/S1API/Growing/SeedDefinition.cs b/S1API/Growing/SeedDefinition.cs index 745a8e17..d3e0886c 100644 --- a/S1API/Growing/SeedDefinition.cs +++ b/S1API/Growing/SeedDefinition.cs @@ -1,9 +1,12 @@ -#if (IL2CPPMELON || IL2CPPBEPINEX) +#if (IL2CPPMELON) using S1Growing = Il2CppScheduleOne.Growing; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1Growing = ScheduleOne.Growing; #endif +using System; +using UnityEngine; + using S1API.Internal.Utils; using S1API.Items; @@ -17,7 +20,7 @@ public class SeedDefinition : ItemDefinition /// /// INTERNAL: Stored reference to the SeedDefinition. /// - internal S1Growing.SeedDefinition S1SeedDefinition => + internal S1Growing.SeedDefinition S1SeedDefinition => CrossType.As(S1ItemDefinition); /// @@ -29,26 +32,24 @@ internal SeedDefinition(S1Growing.SeedDefinition definition) : base(definition) /// /// The prefab that is spawned when planting this seed. /// - public UnityEngine.GameObject FunctionalSeedPrefab => - S1SeedDefinition.FunctionSeedPrefab?.gameObject; + public GameObject? FunctionalSeedPrefab => S1SeedDefinition.FunctionSeedPrefab?.gameObject; /// /// The plant prefab this seed grows into. /// - public UnityEngine.GameObject PlantPrefab => - S1SeedDefinition.PlantPrefab?.gameObject; + public GameObject? PlantPrefab => S1SeedDefinition.PlantPrefab?.gameObject; /// /// Creates an instance of this seed in the world (FunctionalSeed prefab). /// - public UnityEngine.GameObject CreateSeedInstance() + public GameObject CreateSeedInstance() { if (S1SeedDefinition.FunctionSeedPrefab != null) return UnityEngine.Object.Instantiate(S1SeedDefinition.FunctionSeedPrefab).gameObject; - throw new System.NullReferenceException("No FunctionalSeedPrefab assigned to this SeedDefinition!"); + throw new NullReferenceException("No FunctionalSeedPrefab assigned to this SeedDefinition!"); } } -} \ No newline at end of file +} diff --git a/S1API/Growing/SeedInstance.cs b/S1API/Growing/SeedInstance.cs index 97bafe45..f9767b78 100644 --- a/S1API/Growing/SeedInstance.cs +++ b/S1API/Growing/SeedInstance.cs @@ -1,6 +1,6 @@ -#if (IL2CPPMELON || IL2CPPBEPINEX) +#if (IL2CPPMELON) using S1Growing = Il2CppScheduleOne.Growing; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1Growing = ScheduleOne.Growing; #endif @@ -32,7 +32,7 @@ internal SeedInstance(S1Growing.FunctionalSeed functionalSeed) /// /// The underlying GameObject of this seed. /// - private GameObject GameObject => + private GameObject GameObject => S1FunctionalSeed.gameObject; /// @@ -52,4 +52,4 @@ public void ForceExitVial() } } } -} \ No newline at end of file +} diff --git a/S1API/Items/ItemDefinition.cs b/S1API/Items/ItemDefinition.cs index 77869388..24b6e213 100644 --- a/S1API/Items/ItemDefinition.cs +++ b/S1API/Items/ItemDefinition.cs @@ -1,6 +1,6 @@ #if (IL2CPPMELON) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -128,20 +128,41 @@ public virtual ItemInstance CreateInstance(int quantity = 1) return new ItemInstance(inst); } - + /// + /// Gets the globally unique identifier (GUID) of the item, which is equivalent to the ID. + /// public string GUID => ID; + /// + /// Determines whether the specified object is equal to the current object. + /// + /// The object to compare with the current object. + /// true if the specified object is an and has the same S1ItemDefinition; otherwise, false. public override bool Equals(object? obj) => obj is ItemDefinition other && S1ItemDefinition == other.S1ItemDefinition; - public override int GetHashCode() => - S1ItemDefinition?.GetHashCode() ?? 0; + /// + /// Serves as the default hash function. + /// + /// A hash code for the current object based on S1ItemDefinition. + public override int GetHashCode() => S1ItemDefinition.GetHashCode(); + /// + /// Determines whether two instances are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if both instances are equal or have the same S1ItemDefinition; otherwise, false. public static bool operator ==(ItemDefinition? a, ItemDefinition? b) => - ReferenceEquals(a, b) || (a is not null && b is not null && a.S1ItemDefinition == b.S1ItemDefinition); + ReferenceEquals(a, b) || a != null && b != null && a.S1ItemDefinition == b.S1ItemDefinition; - public static bool operator !=(ItemDefinition? a, ItemDefinition? b) => - !(a == b); + /// + /// Determines whether two instances are not equal. + /// + /// The first to compare. + /// The second to compare. + /// true if the instances are not equal; otherwise, false. + public static bool operator !=(ItemDefinition? a, ItemDefinition? b) => !(a == b); } /// diff --git a/S1API/Items/ItemInstance.cs b/S1API/Items/ItemInstance.cs index 2379d571..d3776c63 100644 --- a/S1API/Items/ItemInstance.cs +++ b/S1API/Items/ItemInstance.cs @@ -1,6 +1,6 @@ #if (IL2CPPMELON) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; #endif @@ -46,7 +46,7 @@ public int Quantity /// /// Whether this instance is stackable (based on StackLimit). /// - public bool IsStackable => + public bool IsStackable => Definition.StackLimit > 1; } } diff --git a/S1API/Items/ItemManager.cs b/S1API/Items/ItemManager.cs index 7355ad75..44b9e8aa 100644 --- a/S1API/Items/ItemManager.cs +++ b/S1API/Items/ItemManager.cs @@ -2,7 +2,7 @@ using S1 = Il2CppScheduleOne; using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1 = ScheduleOne; using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; @@ -35,7 +35,7 @@ public static ItemDefinition GetItemDefinition(string itemID) if (CrossType.Is(itemDefinition, out S1ItemFramework.CashDefinition cashDefinition)) return new CashDefinition(cashDefinition); - + return new ItemDefinition(itemDefinition); } } diff --git a/S1API/Items/ItemSlotInstance.cs b/S1API/Items/ItemSlotInstance.cs index c18421bc..2a8cb245 100644 --- a/S1API/Items/ItemSlotInstance.cs +++ b/S1API/Items/ItemSlotInstance.cs @@ -1,7 +1,7 @@ #if (IL2CPPMELON) using S1ItemFramework = Il2CppScheduleOne.ItemFramework; using S1Product = Il2CppScheduleOne.Product; -#elif (MONOMELON || MONOBEPINEX) +#elif (MONOMELON || MONOBEPINEX || IL2CPPBEPINEX) using S1ItemFramework = ScheduleOne.ItemFramework; using S1Product = ScheduleOne.Product; #endif @@ -22,18 +22,18 @@ public class ItemSlotInstance /// INTERNAL: The reference to the item slot in the game. /// internal readonly S1ItemFramework.ItemSlot S1ItemSlot; - + /// /// Creates an item slot instance from the in game slot. /// /// - internal ItemSlotInstance(S1ItemFramework.ItemSlot itemSlot) => + internal ItemSlotInstance(S1ItemFramework.ItemSlot itemSlot) => S1ItemSlot = itemSlot; - + /// /// The quantity of item in this slot. /// - public int Quantity => + public int Quantity => S1ItemSlot.Quantity; /// @@ -46,11 +46,11 @@ public ItemInstance? ItemInstance if (CrossType.Is(S1ItemSlot.ItemInstance, out S1Product.ProductItemInstance productItemInstance)) return new ProductInstance(productItemInstance); - + if (CrossType.Is(S1ItemSlot.ItemInstance, out S1ItemFramework.CashInstance cashInstance)) return new CashInstance(cashInstance); - + if (CrossType.Is(S1ItemSlot.ItemInstance, out S1ItemFramework.ItemInstance itemInstance)) return new ItemInstance(itemInstance); @@ -58,13 +58,13 @@ public ItemInstance? ItemInstance return null; } } - + /// /// Adds a quantity to the item in this slot. /// NOTE: Negative numbers are supported and allowed. /// /// - public void AddQuantity(int amount) => - S1ItemSlot.ChangeQuantity(amount); + public void AddQuantity(int amount) => + S1ItemSlot.ChangeQuantity(amount); } } diff --git a/S1API/S1API.csproj b/S1API/S1API.csproj index 51ca67e3..cc105058 100644 --- a/S1API/S1API.csproj +++ b/S1API/S1API.csproj @@ -56,6 +56,7 @@ + @@ -73,6 +74,7 @@ + @@ -90,7 +92,7 @@ - +