Skip to content

Instantly share code, notes, and snippets.

@Digitalroot
Created June 16, 2021 21:09
Show Gist options
  • Save Digitalroot/7196906fb27975ff357941d8ba1000ac to your computer and use it in GitHub Desktop.
Save Digitalroot/7196906fb27975ff357941d8ba1000ac to your computer and use it in GitHub Desktop.
Add fire damage to BowDraugrFang
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();
FixBowDraugrFang();
}
private static void FixBowDraugrFang()
{
ZLog.Log("FixBowDraugrFang()");
// 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 Draugr Fang the ItemId is 'BowDraugrFang'.
// This foreach should return any Recipe that results in creating a Draugr Fang. 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 == "BowDraugrFang"))
{
instanceMRecipe.m_item.m_itemData.m_shared.m_damages.m_fire = 30f; // Add m_fire damage.
instanceMRecipe.m_item.m_itemData.m_shared.m_damages.m_poison = 0f; // Remove m_poison damage.
ZLog.Log($"Updated {instanceMRecipe.m_item.name} of {instanceMRecipe.name}, set m_fire to {instanceMRecipe.m_item.m_itemData.m_shared.m_damages.m_fire}");
ZLog.Log($"Updated {instanceMRecipe.m_item.name} of {instanceMRecipe.name}, set m_poison to {instanceMRecipe.m_item.m_itemData.m_shared.m_damages.m_poison}");
// 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.
}
}
}
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