Created
June 5, 2021 03:56
-
-
Save Digitalroot/a40e4e93ec749413c37e7a5710888dcf to your computer and use it in GitHub Desktop.
Example of how to add upgrade levels to Atos Arrows XBow without a framework.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BepInEx; | |
using HarmonyLib; | |
using JetBrains.Annotations; | |
using System.Linq; | |
using System.Reflection; | |
using UnityEngine.SceneManagement; | |
namespace Digitalroot.Valheim.AtosArrows.Crafting.Recipes | |
{ | |
/// <summary> | |
/// Example of how to add upgrade levels to Atos Arrows XBow. | |
/// This example does not require any frameworks. | |
/// | |
/// Open Visual Studio and create a new Class Library. Target .Net Framework 4.6.2 | |
/// Add the nuget package 'Pfhoenix.Valheim.ModProjectReferences' to your project. | |
/// | |
/// Replace the code in the Class1.cs file with the code here. | |
/// Build the project or solution. | |
/// Copy the output DLL into the BepInEx plugins directory. Look in [project directory]\bin\Debug | |
/// e.g. my DLL is named Digitalroot.Valheim.AtosArrows.Crafting.Recipes.dll. | |
/// You only need to copy your DLL and nothing else from [project directory]\bin\Debug | |
/// </summary> | |
[BepInPlugin(Guid, Name, Version)] | |
[BepInDependency("com.bepinex.plugins.atosarrows", "0.6.0")] | |
public class Main : BaseUnityPlugin | |
{ | |
public const string Version = "1.0.0"; | |
public const string Name = "Digitalroot Atos Arrow Crafting Recipes"; | |
public const string Guid = "digitalroot.mods.AtosArrows.Crafting.Recipes"; | |
public const string Namespace = "Digitalroot.Valheim.AtosArrows.Crafting.Recipes"; | |
private Harmony _harmony; | |
[UsedImplicitly] | |
private void Awake() | |
{ | |
_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), Guid); | |
} | |
[UsedImplicitly] | |
private void OnDestroy() | |
{ | |
_harmony?.UnpatchSelf(); | |
} | |
} | |
public class Patch | |
{ | |
[HarmonyPatch(typeof(ObjectDB), "Awake")] | |
public class PatchObjectDBAwake | |
{ | |
[UsedImplicitly] | |
[HarmonyPostfix] | |
[HarmonyPriority(Priority.Normal)] | |
[HarmonyAfter("com.bepinex.plugins.jotunnlib", "com.bepinex.plugins.atosarrows")] | |
public static void Postfix() | |
{ | |
ZLog.Log($"{Main.Namespace}.{MethodBase.GetCurrentMethod().DeclaringType?.Name}.{MethodBase.GetCurrentMethod().Name}"); | |
FixXBow(); | |
} | |
} | |
private static void FixXBow() | |
{ | |
ZLog.Log("Updating Atos Arrow Recipes"); | |
// This is normal checking if ObjectDB is ready. | |
if (!(ObjectDB.instance != null && ObjectDB.instance.m_items.Count != 0 && ObjectDB.instance.GetItemPrefab("Amber") != null)) | |
{ | |
ZLog.Log("ObjectDBReady not ready - skipping"); | |
return; | |
} | |
// com.bepinex.plugins.atosarrows waits to load until the Active Scene is 'main'. Most other item mods load on Awake and CopyOtherDB | |
if (SceneManager.GetActiveScene().name != "main") | |
{ | |
ZLog.Log("Not at 'main' Scene - skipping"); | |
return; | |
} | |
// We need to know the ItemId of the item we want to change. For the Crossbow the ItemId is 'XBow'. | |
// This foreach should return any Recipe that results in creating a XBow. This should solve an | |
// edge case where an item has more then one Recipe to craft it. | |
foreach (Recipe instanceMRecipe in ObjectDB.instance.m_recipes.Where(r => r.m_item?.name == "XBow")) | |
{ | |
instanceMRecipe.m_item.m_itemData.m_shared.m_maxQuality = 3; // Sets the max level an item can be upgraded to. | |
ZLog.Log($"Updated {instanceMRecipe.m_item.name} of {instanceMRecipe.name}, set m_maxQuality to {instanceMRecipe.m_item.m_itemData.m_shared.m_maxQuality}"); | |
// com.bepinex.plugins.atosarrows did not define m_amountPerLevel values. Without these the item is upgradable for free. | |
// The original Recipe uses Crystal, BlackMetal, FineWood and LinenThread. For the upgrade only more Crystal, and BlackMetal | |
// are required. However more FineWood and LinenThread could also be required. | |
foreach (Piece.Requirement requirement in instanceMRecipe.m_resources) | |
{ | |
switch (requirement.m_resItem.name) | |
{ | |
case "Crystal": | |
requirement.m_amountPerLevel = 5; | |
break; | |
case "BlackMetal": | |
requirement.m_amountPerLevel = 10; | |
break; | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment