using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CustomWeaponDrops")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HP")]
[assembly: AssemblyProduct("CustomWeaponDrops")]
[assembly: AssemblyCopyright("Copyright © HP 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("096c07b4-f7b6-4645-b628-fe006ac828d5")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace YouDied.Valheim;
[BepInPlugin("YouDied.CustomWeaponDrops", "Custom Weapon Drops", "2.2.4")]
public class CustomWeaponDrops : BaseUnityPlugin
{
[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
public class GenerateDropPatch
{
private static void Postfix(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result)
{
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Invalid comparison between Unknown and I4
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
{
return;
}
Character component = ((Component)__instance).gameObject.GetComponent<Character>();
if ((Object)(object)component == (Object)null)
{
return;
}
string text = ((Object)component).name.Replace("(Clone)", "").Trim();
Dictionary<string, ConfigEntry<string>> dictionary;
int value;
float num;
switch (component.GetLevel())
{
case 2:
dictionary = OneStarDrops;
value = OneStarWeaponQuality.Value;
num = 1f;
break;
case 3:
dictionary = TwoStarDrops;
value = TwoStarWeaponQuality.Value;
num = 1f;
break;
default:
dictionary = NoStarDrops;
value = NoStarWeaponQuality.Value;
num = NoStarDropChance.Value;
break;
}
if (!dictionary.ContainsKey(text) || Random.value > num)
{
return;
}
Vector3 centerPoint = component.GetCenterPoint();
if (UseEquippedWeapon.Contains(text))
{
Humanoid component2 = ((Component)__instance).gameObject.GetComponent<Humanoid>();
if ((Object)(object)component2 == (Object)null)
{
return;
}
ItemData currentWeapon = component2.GetCurrentWeapon();
if ((Object)(object)currentWeapon?.m_dropPrefab != (Object)null)
{
if (WeaponMap.TryGetValue(((Object)currentWeapon.m_dropPrefab).name, out var value2))
{
SpawnItemDrop(value2, value, centerPoint);
}
else
{
Debug.LogWarning((object)("[CustomWeaponDrops] No weapon mapping for '" + ((Object)currentWeapon.m_dropPrefab).name + "' on " + text));
}
}
ItemData leftItem = component2.LeftItem;
if ((Object)(object)leftItem?.m_dropPrefab != (Object)null && (int)leftItem.m_shared.m_itemType == 5)
{
if (ShieldMap.TryGetValue(((Object)leftItem.m_dropPrefab).name, out var value3))
{
SpawnItemDrop(value3, value, centerPoint);
}
else
{
Debug.LogWarning((object)("[CustomWeaponDrops] No shield mapping for '" + ((Object)leftItem.m_dropPrefab).name + "' on " + text));
}
}
return;
}
string text2 = dictionary[text].Value.Trim();
if (string.IsNullOrEmpty(text2))
{
return;
}
string[] array = text2.Split(new char[1] { ',' });
foreach (string text3 in array)
{
string text4 = text3.Trim();
if (!string.IsNullOrEmpty(text4))
{
if (WeaponMap.TryGetValue(text4, out var value4))
{
text4 = value4;
}
SpawnItemDrop(text4, value, centerPoint);
}
}
}
private static void SpawnItemDrop(string prefabName, int quality, Vector3 position)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
if ((Object)(object)prefab == (Object)null)
{
Debug.LogWarning((object)("[CustomWeaponDrops] '" + prefabName + "' not found in ZNetScene"));
return;
}
Vector3 val = Random.insideUnitSphere * 0.5f;
val.y = Mathf.Abs(val.y);
Quaternion val2 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
GameObject val3 = Object.Instantiate<GameObject>(prefab, position + val, val2);
ItemDrop component = val3.GetComponent<ItemDrop>();
if ((Object)(object)component != (Object)null)
{
component.m_itemData.m_quality = quality;
component.m_itemData.m_worldLevel = (byte)Game.m_worldLevel;
}
Rigidbody component2 = val3.GetComponent<Rigidbody>();
if ((Object)(object)component2 != (Object)null)
{
Vector3 val4 = Random.insideUnitSphere * 5f;
val4.y = Mathf.Abs(val4.y);
component2.AddForce(val4, (ForceMode)2);
}
}
}
public static Dictionary<string, ConfigEntry<string>> NoStarDrops;
public static Dictionary<string, ConfigEntry<string>> OneStarDrops;
public static Dictionary<string, ConfigEntry<string>> TwoStarDrops;
public static ConfigEntry<float> NoStarDropChance;
public static ConfigEntry<int> NoStarWeaponQuality;
public static ConfigEntry<int> OneStarWeaponQuality;
public static ConfigEntry<int> TwoStarWeaponQuality;
private static readonly Dictionary<string, string> WeaponMap = new Dictionary<string, string>
{
{ "skeleton_sword", "SwordBronze" },
{ "skeleton_sword2", "SwordBronze" },
{ "skeleton_bow", "BowHuntsman" },
{ "skeleton_bow2", "BowHuntsman" },
{ "skeleton_mace", "MaceIron" },
{ "GoblinClub", "Club" },
{ "GoblinSpear", "SpearWolfFang" },
{ "GoblinSword", "SwordBlackmetal" },
{ "GoblinTorch", "Torch" },
{ "draugr_axe", "AxeIron" },
{ "draugr_bow", "BowHuntsman" },
{ "draugr_sword", "SwordIron" },
{ "charred_bow", "BowAshlands" }
};
private static readonly Dictionary<string, string> ShieldMap = new Dictionary<string, string>
{
{ "ShieldWood", "ShieldWood" },
{ "ShieldBronzeBuckler", "ShieldBronzeBuckler" },
{ "ShieldBanded", "ShieldBanded" }
};
private static readonly HashSet<string> UseEquippedWeapon = new HashSet<string> { "Skeleton", "Goblin", "Draugr" };
private readonly string[] enemies = new string[7] { "Skeleton", "Skeleton_Poison", "Goblin", "Draugr", "Draugr_Elite", "Draugr_Ranged", "Charred_Archer" };
private void Awake()
{
NoStarDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "NoStarDropChance", 0.05f, "Chance (0.0 - 1.0) that a no-star enemy drops their weapon/shield. Default: 0.05 (5%)");
NoStarWeaponQuality = ((BaseUnityPlugin)this).Config.Bind<int>("Global", "NoStarWeaponQuality", 1, "Item quality level of weapons/shields dropped by no-star enemies.");
OneStarWeaponQuality = ((BaseUnityPlugin)this).Config.Bind<int>("Global", "OneStarWeaponQuality", 2, "Item quality level of weapons/shields dropped by 1-star enemies.");
TwoStarWeaponQuality = ((BaseUnityPlugin)this).Config.Bind<int>("Global", "TwoStarWeaponQuality", 3, "Item quality level of weapons/shields dropped by 2-star enemies.");
NoStarDrops = new Dictionary<string, ConfigEntry<string>>();
OneStarDrops = new Dictionary<string, ConfigEntry<string>>();
TwoStarDrops = new Dictionary<string, ConfigEntry<string>>();
string[] array = enemies;
foreach (string text in array)
{
string text2 = (UseEquippedWeapon.Contains(text) ? (" Leave empty — " + text + " drops its equipped weapon/shield automatically.") : "");
NoStarDrops[text] = ((BaseUnityPlugin)this).Config.Bind<string>(text, "NoStar", GetDefaultWeapon(text), "Prefab name to drop for no-star " + text + ". Empty = no drop." + text2);
OneStarDrops[text] = ((BaseUnityPlugin)this).Config.Bind<string>(text, "1Star", GetDefaultWeapon(text), "Prefab name to drop for 1-star " + text + ". Empty = no drop." + text2);
TwoStarDrops[text] = ((BaseUnityPlugin)this).Config.Bind<string>(text, "2Star", GetDefaultWeapon(text), "Prefab name to drop for 2-star " + text + ". Empty = no drop." + text2);
}
Harmony.CreateAndPatchAll(typeof(GenerateDropPatch), (string)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Custom Weapon Drops v2.2.4 Loaded! (YouDied)");
}
private static string GetDefaultWeapon(string enemy)
{
return enemy switch
{
"Skeleton" => "",
"Skeleton_Poison" => "MaceIron",
"Goblin" => "",
"Draugr" => "",
"Draugr_Elite" => "SwordIron",
"Draugr_Ranged" => "BowHuntsman",
"Charred_Archer" => "BowAshlands",
_ => "",
};
}
}