diff --git a/ArtifactOfSequencing/ArtifactOfSequencing.cs b/ArtifactOfSequencing/ArtifactOfSequencing.cs new file mode 100644 index 0000000..e2dadad --- /dev/null +++ b/ArtifactOfSequencing/ArtifactOfSequencing.cs @@ -0,0 +1,151 @@ +using BepInEx; +using BepInEx.Configuration; +using R2API; +using R2API.Utils; +using RoR2; +using System; +using System.Linq; +using UnityEngine; + +namespace Chev +{ + [BepInDependency("com.bepis.r2api")] + [BepInPlugin("com.Chev.ArtifactOfSequencing", "Artifact of Sequencing", "1.0.0")] + [NetworkCompatibility(CompatibilityLevel.EveryoneMustHaveMod, VersionStrictness.EveryoneNeedSameModVersion)] + [R2APISubmoduleDependency(nameof(ArtifactAPI))] + public class ArtifactOfSequencingMod : BaseUnityPlugin + { + public static ArtifactDef Artifact; + + public static ItemDef CommonItem; + public static ItemDef UncommonItem; + public static ItemDef LegendaryItem; + public static ItemDef BossItem; + public static ItemDef LunarItem; + + private static readonly System.Random _random = new System.Random(); + + public static ConfigEntry CommonItemCount { get; set; } + public static ConfigEntry UncommonItemCount { get; set; } + public static ConfigEntry LegendaryItemCount { get; set; } + public static ConfigEntry BossItemCount { get; set; } + public static ConfigEntry LunarItemCount { get; set; } + + public void Awake() + { + // Initialize config + CommonItemCount = Config.Bind("Quantities", "CommonItemCount", 1, "Quantity of the common (white) item to start with."); + UncommonItemCount = Config.Bind("Quantities", "UncommonItemCount", 1, "Quantity of the uncommon (green) item to start with."); + LegendaryItemCount = Config.Bind("Quantities", "LegendaryItemCount", 1, "Quantity of the legendary (red) item to start with."); + BossItemCount = Config.Bind("Quantities", "BossItemCount", 1, "Quantity of the boss (yellow) item to start with."); + LunarItemCount = Config.Bind("Quantities", "LunarItemCount", 1, "Quantity of the lunar (blue) item to start with."); + + // Initialize the artifact + Artifact = ScriptableObject.CreateInstance(); + + // Artifact info + Artifact.nameToken = "Artifact of Sequencing"; + Artifact.descriptionToken = "Spawn with a single item of every tier. Any picked up items will be converted to the starting item of the same tier."; + Artifact.smallIconSelectedSprite = LoadIcon(ArtifactOfSequencing.Properties.Resources.texArtifactSequencingEnabled); + Artifact.smallIconDeselectedSprite = LoadIcon(ArtifactOfSequencing.Properties.Resources.texArtifactSequencingDisabled); + + // Add our custom artifact to the artifact list + // This uses the ArtifactAPI submodule in R2API + ArtifactAPI.Add(Artifact); + + // On stage start event + // This is when we add our items + //Stage.onStageStartGlobal += AddBeginningItems; + Run.onRunStartGlobal += AddBeginningItems; + + Logger.LogMessage("Loaded mod com.Chev.ArtifactOfSequencing"); + } + + /// + /// Loads a Unity Sprite from resources. + /// + /// The byte array of the resource. + /// + private Sprite LoadIcon(Byte[] resourceBytes) + { + if (resourceBytes == null) + throw new ArgumentNullException(nameof(resourceBytes)); + + Texture2D iconTex = new Texture2D(64, 64, TextureFormat.RGBA32, false); + iconTex.LoadImage(resourceBytes); + + return Sprite.Create(iconTex, new Rect(0f, 0f, iconTex.width, iconTex.height), new Vector2(0.5f, 0.5f)); + } + + /// + /// Gets a random item from a chosen tier. + /// + /// The item tier, e.g. common, uncommon, legendary, lunar, boss + /// + private ItemDef RandomItem(ItemTier tier) + { + ItemDef[] itemDefs = typeof(ItemCatalog).GetFieldValue("itemDefs"); + + ItemDef[] itemsOfTier = itemDefs.Where(item => item.tier == tier).ToArray(); + + return itemsOfTier[_random.Next(0, itemsOfTier.Length)]; + } + + private ItemDef ItemFromTier(ItemTier tier) + { + switch (tier) + { + case ItemTier.Tier1: + return CommonItem; + case ItemTier.Tier2: + return UncommonItem; + case ItemTier.Tier3: + return LegendaryItem; + case ItemTier.Boss: + return BossItem; + case ItemTier.Lunar: + return LunarItem; + default: + return null; + } + } + + public void AddBeginningItems(Run run) + { + CharacterMaster master = PlayerCharacterMasterController.instances[0].master; + + if (master) + { + // Set starting items + CommonItem = RandomItem(ItemTier.Tier1); + UncommonItem = RandomItem(ItemTier.Tier2); + LegendaryItem = RandomItem(ItemTier.Tier3); + BossItem = RandomItem(ItemTier.Boss); + LunarItem = RandomItem(ItemTier.Lunar); + + // Give the starting items + master.inventory.GiveItem(CommonItem, CommonItemCount.Value); + master.inventory.GiveItem(UncommonItem, UncommonItemCount.Value); + master.inventory.GiveItem(LegendaryItem, LegendaryItemCount.Value); + master.inventory.GiveItem(BossItem, BossItemCount.Value); + master.inventory.GiveItem(LunarItem, LunarItemCount.Value); + + // Called every time an item is given + // If the item is not a starter item, remove it and give the starter item + Inventory.onServerItemGiven += (inv, itemIndex, count) => + { + ItemDef starterItemToCompare = ItemFromTier(ItemCatalog.GetItemDef(itemIndex).tier); + + // If they are different items + if (starterItemToCompare != null && starterItemToCompare.itemIndex != itemIndex) + { + int itemCount = inv.GetItemCount(itemIndex); + + inv.RemoveItem(itemIndex, itemCount); + inv.GiveItem(starterItemToCompare, itemCount); + } + }; + } + } + } +} \ No newline at end of file diff --git a/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate.csproj b/ArtifactOfSequencing/ArtifactOfSequencing.csproj similarity index 79% rename from RoR2-SacrificeDropRate/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate.csproj rename to ArtifactOfSequencing/ArtifactOfSequencing.csproj index 5f01a29..e1ae03f 100644 --- a/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate.csproj +++ b/ArtifactOfSequencing/ArtifactOfSequencing.csproj @@ -2,34 +2,29 @@ netstandard2.0 - RoR2_SacrificeDropRate - SacrificeDropRate H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\0Harmony.dll + + H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\0Harmony20.dll + H:\SteamLibrary\steamapps\common\Risk of Rain 2\Risk of Rain 2_Data\Managed\Assembly-CSharp.dll - - H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\monomod\Assembly-CSharp.R2API.mm.dll - H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\BepInEx.dll H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\BepInEx.Harmony.dll - - H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\patchers\BepInEx.MonoMod.Loader\BepInEx.MonoMod.Loader.dll - H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\BepInEx.Preloader.dll - - H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\plugins\R2API\MMHOOK_Assembly-CSharp.dll + + H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\HarmonyXInterop.dll H:\SteamLibrary\steamapps\common\Risk of Rain 2\BepInEx\core\Mono.Cecil.dll @@ -58,9 +53,27 @@ H:\SteamLibrary\steamapps\common\Risk of Rain 2\Risk of Rain 2_Data\Managed\UnityEngine.CoreModule.dll + + H:\SteamLibrary\steamapps\common\Risk of Rain 2\Risk of Rain 2_Data\Managed\UnityEngine.ImageConversionModule.dll + H:\SteamLibrary\steamapps\common\Risk of Rain 2\Risk of Rain 2_Data\Managed\UnityEngine.Networking.dll + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + diff --git a/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate.sln b/ArtifactOfSequencing/ArtifactOfSequencing.sln similarity index 54% rename from RoR2-SacrificeDropRate/RoR2-SacrificeDropRate.sln rename to ArtifactOfSequencing/ArtifactOfSequencing.sln index 3eb9d45..f2d31c2 100644 --- a/RoR2-SacrificeDropRate/RoR2-SacrificeDropRate.sln +++ b/ArtifactOfSequencing/ArtifactOfSequencing.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.30204.135 +VisualStudioVersion = 16.0.31005.135 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoR2-SacrificeDropRate", "RoR2-SacrificeDropRate\RoR2-SacrificeDropRate.csproj", "{85B9C64B-B9FD-474F-89B4-9590529E677F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArtifactOfSequencing", "ArtifactOfSequencing.csproj", "{F79372C6-A1F3-4F5E-A784-F6C06D2ED0C4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {85B9C64B-B9FD-474F-89B4-9590529E677F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {85B9C64B-B9FD-474F-89B4-9590529E677F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {85B9C64B-B9FD-474F-89B4-9590529E677F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {85B9C64B-B9FD-474F-89B4-9590529E677F}.Release|Any CPU.Build.0 = Release|Any CPU + {F79372C6-A1F3-4F5E-A784-F6C06D2ED0C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F79372C6-A1F3-4F5E-A784-F6C06D2ED0C4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F79372C6-A1F3-4F5E-A784-F6C06D2ED0C4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F79372C6-A1F3-4F5E-A784-F6C06D2ED0C4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {10D54B89-E06E-428E-AE42-911FF165AE02} + SolutionGuid = {1CBC6AD0-C30C-49DF-8722-593A8A0F9DC8} EndGlobalSection EndGlobal diff --git a/ArtifactOfSequencing/Properties/Resources.Designer.cs b/ArtifactOfSequencing/Properties/Resources.Designer.cs new file mode 100644 index 0000000..92773db --- /dev/null +++ b/ArtifactOfSequencing/Properties/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ArtifactOfSequencing.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ArtifactOfSequencing.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] texArtifactSequencingDisabled { + get { + object obj = ResourceManager.GetObject("texArtifactSequencingDisabled", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] texArtifactSequencingEnabled { + get { + object obj = ResourceManager.GetObject("texArtifactSequencingEnabled", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/ArtifactOfSequencing/Properties/Resources.resx b/ArtifactOfSequencing/Properties/Resources.resx new file mode 100644 index 0000000..a40721e --- /dev/null +++ b/ArtifactOfSequencing/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + texArtifactSequencingDisabled.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + texArtifactSequencingEnabled.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ArtifactOfSequencing/Properties/texArtifactSequencingDisabled.png b/ArtifactOfSequencing/Properties/texArtifactSequencingDisabled.png new file mode 100644 index 0000000..1a6baaa Binary files /dev/null and b/ArtifactOfSequencing/Properties/texArtifactSequencingDisabled.png differ diff --git a/ArtifactOfSequencing/Properties/texArtifactSequencingEnabled.png b/ArtifactOfSequencing/Properties/texArtifactSequencingEnabled.png new file mode 100644 index 0000000..d144c63 Binary files /dev/null and b/ArtifactOfSequencing/Properties/texArtifactSequencingEnabled.png differ