using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using AlmanacClasses.API;
using AzuExtendedPlayerInventory;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Deathlink.Common;
using Deathlink.Death;
using Deathlink.external;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SimpleJson;
using Splatform;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ValRougelike")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValRougelike")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace Backpacks
{
[PublicAPI]
public static class API
{
public static EpicMMOSystem_API.API_State state;
private static MethodInfo eCountItemsInBackpacks;
private static MethodInfo eAddItemToBackpack;
private static MethodInfo eDeleteItemsFromBackpacks;
private static MethodInfo eGetEquippedBackpackInventory;
private static MethodInfo eGetAllBackpackInventories;
public static int CountItemsInBackpacks(Inventory inventory, string name, bool onlyRemoveable = true)
{
return (int)eCountItemsInBackpacks?.Invoke(null, new object[3] { inventory, name, onlyRemoveable });
}
public static bool IsItemInBackpacks(Inventory inventory, string name)
{
return CountItemsInBackpacks(inventory, name) > 0;
}
public static bool AddItemToBackpack(ItemData backpack, ItemData item)
{
return (bool)eAddItemToBackpack?.Invoke(null, new object[2] { backpack, item });
}
public static bool DeleteItemsFromBackpacks(Inventory inventory, string name, int count = 1)
{
return (bool)eDeleteItemsFromBackpacks?.Invoke(null, new object[3] { inventory, name, count });
}
public static Inventory? GetEquippedBackpackInventory()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
return (Inventory)(eGetEquippedBackpackInventory?.Invoke(null, new object[0]));
}
public static List<Inventory> GetAllBackpackInventories(Inventory inventory)
{
return (List<Inventory>)(eGetAllBackpackInventories?.Invoke(null, new object[1] { inventory }));
}
public static void Init()
{
EpicMMOSystem_API.API_State aPI_State = state;
if ((uint)(aPI_State - 1) > 1u)
{
if (Type.GetType("Backpacks.API, Backpacks") == null)
{
state = EpicMMOSystem_API.API_State.NotInstalled;
return;
}
state = EpicMMOSystem_API.API_State.Ready;
Type? type = Type.GetType("Backpacks.API, Backpacks");
eCountItemsInBackpacks = type.GetMethod("CountItemsInBackpacks", BindingFlags.Static | BindingFlags.Public);
eAddItemToBackpack = type.GetMethod("AddItemToBackpack", BindingFlags.Static | BindingFlags.Public);
eDeleteItemsFromBackpacks = type.GetMethod("DeleteItemsFromBackpacks", BindingFlags.Static | BindingFlags.Public);
eGetEquippedBackpackInventory = type.GetMethod("GetEquippedBackpackInventory", BindingFlags.Static | BindingFlags.Public);
eGetAllBackpackInventories = type.GetMethod("GetAllBackpackInventories", BindingFlags.Static | BindingFlags.Public);
}
}
}
}
namespace AzuExtendedPlayerInventory
{
[PublicAPI]
public class API
{
public delegate void SlotAddedHandler(string slotName);
public delegate void SlotRemovedHandler(string slotName);
public static event Action<Hud>? OnHudAwake;
public static event Action<Hud>? OnHudAwakeComplete;
public static event Action<Hud>? OnHudUpdate;
public static event Action<Hud>? OnHudUpdateComplete;
public static event SlotAddedHandler? SlotAdded;
public static event SlotRemovedHandler? SlotRemoved;
public static bool IsLoaded()
{
return false;
}
public static bool AddSlot(string slotName, Func<Player, ItemData?> getItem, Func<ItemData, bool> isValid, int index = -1)
{
return false;
}
public static bool RemoveSlot(string slotName)
{
return false;
}
public static SlotInfo GetSlots()
{
return new SlotInfo();
}
public static SlotInfo GetQuickSlots()
{
return new SlotInfo();
}
public static List<ItemData> GetQuickSlotsItems()
{
return new List<ItemData>();
}
public static int GetAddedRows(int width)
{
return 0;
}
}
[PublicAPI]
public class SlotInfo
{
public string[] SlotNames { get; set; } = new string[0];
public Vector2[] SlotPositions { get; set; } = (Vector2[])(object)new Vector2[0];
public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = new Func<Player, ItemData>[0];
public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = new Func<ItemData, bool>[0];
}
}
namespace AlmanacClasses.API
{
public static class ClassesAPI
{
private static readonly MethodInfo? API_AddExperience;
private static readonly MethodInfo? API_GetLevel;
private static readonly MethodInfo? API_GetCharacteristic;
public static void AddEXP(int amount)
{
API_AddExperience?.Invoke(null, new object[1] { amount });
}
public static int GetLevel()
{
return (int)(API_GetLevel?.Invoke(null, null) ?? ((object)0));
}
public static int GetCharacteristic(string type)
{
return (int)(API_GetCharacteristic?.Invoke(null, new object[1] { type }) ?? ((object)0));
}
public static int GetConstitution()
{
return GetCharacteristic("Constitution");
}
public static int GetDexterity()
{
return GetCharacteristic("Dexterity");
}
public static int GetStrength()
{
return GetCharacteristic("Strength");
}
public static int GetIntelligence()
{
return GetCharacteristic("Intelligence");
}
public static int GetWisdom()
{
return GetCharacteristic("Wisdom");
}
static ClassesAPI()
{
Type type = Type.GetType("AlmanacClasses.API.API, AlmanacClasses");
if ((object)type != null)
{
API_AddExperience = type.GetMethod("AddExperience", BindingFlags.Static | BindingFlags.Public);
API_GetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public);
API_GetCharacteristic = type.GetMethod("GetCharacteristic", BindingFlags.Static | BindingFlags.Public);
}
}
}
}
namespace Deathlink
{
internal class Logger
{
public static LogLevel Level = (LogLevel)16;
public static void enableDebugLogging(object sender, EventArgs e)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (ValConfig.EnableDebugMode.Value)
{
Level = (LogLevel)32;
}
else
{
Level = (LogLevel)16;
}
}
public static void CheckEnableDebugLogging()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (ValConfig.EnableDebugMode.Value)
{
Level = (LogLevel)32;
}
else
{
Level = (LogLevel)16;
}
}
public static void LogDebug(string message)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)Level >= 32)
{
Deathlink.Log.LogInfo((object)message);
}
}
public static void LogInfo(string message)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)Level >= 16)
{
Deathlink.Log.LogInfo((object)message);
}
}
public static void LogWarning(string message)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
if ((int)Level >= 4)
{
Deathlink.Log.LogWarning((object)message);
}
}
public static void LogError(string message)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
if ((int)Level >= 2)
{
Deathlink.Log.LogError((object)message);
}
}
}
public static class Extensions
{
private static readonly List<ItemType> EquipmentTypes = new List<ItemType>
{
(ItemType)7,
(ItemType)12,
(ItemType)6,
(ItemType)11,
(ItemType)4,
(ItemType)5,
(ItemType)19,
(ItemType)17,
(ItemType)18,
(ItemType)3,
(ItemType)14,
(ItemType)22,
(ItemType)20,
(ItemType)24
};
public static List<ItemData> GetEquipment(this List<ItemData> list)
{
return list.Where((ItemData x) => EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList();
}
public static List<ItemData> GetNotEquipment(this List<ItemData> list)
{
return list.Where((ItemData x) => !EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList();
}
public static bool IsEquipment(this ItemData item)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
if (EquipmentTypes.Contains(item.m_shared.m_itemType))
{
return true;
}
return false;
}
}
[BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.8.7")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class Deathlink : BaseUnityPlugin
{
public const string PluginGUID = "MidnightsFX.Deathlink";
public const string PluginName = "Deathlink";
public const string PluginVersion = "0.8.7";
public ValConfig cfg;
internal static AssetBundle EmbeddedResourceBundle;
internal static bool AzuEPILoaded = false;
internal static bool RustyAlmanacClassesLoaded = false;
internal static bool WackyMMOLoaded = false;
public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();
public static ManualLogSource Log;
public void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
cfg = new ValConfig(((BaseUnityPlugin)this).Config);
AddLocalizations();
EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Deathlink.AssetsEmbedded.deathless", typeof(Deathlink).Assembly);
DeathProgressionSkill.SetupDeathSkill();
if (API.IsLoaded())
{
AzuEPILoaded = true;
}
if (BepInExUtils.GetPlugins(false).Keys.Contains("WackyMole.EpicMMOSystem"))
{
EpicMMOSystem_API.Init();
if (EpicMMOSystem_API.state == EpicMMOSystem_API.API_State.Ready)
{
WackyMMOLoaded = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API loaded.");
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API installed but API not ready.");
}
}
if (BepInExUtils.GetPlugins(false).Keys.Contains("RustyMods.AlmanacClasses"))
{
RustyAlmanacClassesLoaded = true;
}
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
DeathConfigurationData.Init();
TerminalCommands.AddCommands();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Death is not the end.");
}
public static DataObjects.DeathChoiceLevel pcfg()
{
return DeathConfigurationData.playerDeathConfiguration;
}
private void AddLocalizations()
{
Localization = LocalizationManager.Instance.GetLocalization();
string text = Path.Combine(Paths.ConfigPath, "Deathlink", "localizations");
Directory.CreateDirectory(text);
string[] manifestResourceNames = typeof(Deathlink).Assembly.GetManifestResourceNames();
foreach (string text2 in manifestResourceNames)
{
if (!text2.Contains("Localizations"))
{
continue;
}
string text3 = Regex.Replace(ReadEmbeddedResourceFile(text2), "\\/\\/.*", "");
Dictionary<string, string> internal_localization = SimpleJson.DeserializeObject<Dictionary<string, string>>(text3);
string[] array = text2.Split(new char[1] { '.' });
if (File.Exists(text + "/" + array[2] + ".json"))
{
string text4 = File.ReadAllText(text + "/" + array[2] + ".json");
try
{
Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text4);
UpdateLocalizationWithMissingKeys(internal_localization, dictionary);
((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text + "/" + array[2] + ".json"));
File.WriteAllText(text + "/" + array[2] + ".json", SimpleJson.SerializeObject((object)dictionary));
string text5 = File.ReadAllText(text + "/" + array[2] + ".json");
Localization.AddJsonFile(array[2], text5);
}
catch
{
File.WriteAllText(text + "/" + array[2] + ".json", text3);
((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2));
Localization.AddJsonFile(array[2], text3);
}
}
else
{
File.WriteAllText(text + "/" + array[2] + ".json", text3);
((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2));
Localization.AddJsonFile(array[2], text3);
}
((BaseUnityPlugin)this).Logger.LogDebug((object)("Added localization: '" + array[2] + "'"));
}
}
private void UpdateLocalizationWithMissingKeys(Dictionary<string, string> internal_localization, Dictionary<string, string> cached_localization)
{
if (internal_localization.Keys.Count == cached_localization.Keys.Count)
{
return;
}
((BaseUnityPlugin)this).Logger.LogDebug((object)"Cached localization was missing some entries. They will be added.");
foreach (KeyValuePair<string, string> item in internal_localization)
{
if (!cached_localization.ContainsKey(item.Key))
{
cached_localization.Add(item.Key, item.Value);
}
}
}
private string ReadEmbeddedResourceFile(string filename)
{
using Stream stream = typeof(Deathlink).Assembly.GetManifestResourceStream(filename);
using StreamReader streamReader = new StreamReader(stream);
return streamReader.ReadToEnd();
}
public static List<T> shuffleList<T>(List<T> inputList)
{
int i = 0;
int count = inputList.Count;
int num = 0;
T val = default(T);
List<T> list = new List<T>();
list.AddRange(inputList);
for (; i < count; i++)
{
num = Random.Range(i, list.Count);
val = list[i];
list[i] = list[num];
list[num] = val;
}
return list;
}
}
}
namespace Deathlink.external
{
public static class EpicMMOSystem_API
{
public enum API_State
{
NotReady,
NotInstalled,
Ready
}
public enum Attribut
{
Strength,
Agility,
Intellect,
Body,
Vigour,
Special
}
public static API_State state;
private static MethodInfo eGetLevel;
private static MethodInfo eAddExp;
private static MethodInfo eGetAttribute;
private static MethodInfo eGetAttributeRusty;
private static MethodInfo eSetSingleRate;
public static int GetLevel()
{
int result = 0;
Init();
if (eGetLevel != null)
{
result = (int)eGetLevel.Invoke(null, null);
}
return result;
}
public static int GetAttribute(Attribut attribute)
{
int result = 0;
Init();
if (eGetAttribute != null)
{
result = (int)eGetAttribute.Invoke(null, new object[1] { attribute });
}
return result;
}
public static int GetAttributeRusty(string attribute)
{
int result = 0;
Init();
if (eGetAttributeRusty != null)
{
result = (int)eGetAttributeRusty.Invoke(null, new object[1] { attribute });
}
return result;
}
public static void AddExp(int value)
{
Init();
eAddExp?.Invoke(null, new object[1] { value });
}
public static void SetSingleRate(float rate)
{
Init();
eSetSingleRate?.Invoke(null, new object[1] { rate });
}
public static void Init()
{
API_State aPI_State = state;
if ((uint)(aPI_State - 1) > 1u)
{
if (Type.GetType("EpicMMOSystem.EpicMMOSystem, EpicMMOSystem") == null)
{
state = API_State.NotInstalled;
return;
}
state = API_State.Ready;
Type? type = Type.GetType("API.EMMOS_API, EpicMMOSystem");
eGetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public);
eAddExp = type.GetMethod("AddExp", BindingFlags.Static | BindingFlags.Public);
eGetAttribute = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public);
eGetAttributeRusty = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public);
eSetSingleRate = type.GetMethod("SetSingleRate", BindingFlags.Static | BindingFlags.Public);
}
}
}
}
namespace Deathlink.Death
{
public static class Compendium
{
[HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")]
public static class TextsDialog_UpdateTextsList_Patch
{
public static void Postfix(TextsDialog __instance)
{
AddDeathLinkExplanationPage(__instance);
}
private static void AddDeathLinkExplanationPage(TextsDialog textsDialog)
{
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Expected O, but got Unknown
DataObjects.DeathChoiceLevel playerDeathConfiguration = DeathConfigurationData.playerDeathConfiguration;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("<size=48>" + Localization.instance.Localize("$comp_header") + ": <color=" + specialColor + ">" + playerDeathConfiguration.DisplayName + "</color></size>");
stringBuilder.AppendLine();
stringBuilder.AppendLine("<size=30><b>Death Effects</b></size>");
stringBuilder.AppendLine(playerDeathConfiguration.GetDeathStyleDescription());
stringBuilder.AppendLine();
if (playerDeathConfiguration.SkillModifiers.Count > 0)
{
stringBuilder.AppendLine("<size=30><b>Skill Modifiers</b></size>");
stringBuilder.AppendLine(playerDeathConfiguration.GetSkillModiferDescription());
stringBuilder.AppendLine();
}
if (playerDeathConfiguration.ResourceModifiers.Count > 0)
{
stringBuilder.AppendLine("<size=30><b>Resource Modifiers</b></size>");
stringBuilder.AppendLine(playerDeathConfiguration.GetResourceModiferDescription());
stringBuilder.AppendLine();
}
if (playerDeathConfiguration.DeathLootModifiers.Count > 0)
{
stringBuilder.AppendLine("<size=30><b>Loot Modifiers</b></size>");
stringBuilder.AppendLine(playerDeathConfiguration.GetLootModifiersDescription());
stringBuilder.AppendLine();
}
textsDialog.m_texts.Insert(0, new TextInfo(Localization.instance.Localize("$deathlink_settings"), Localization.instance.Localize(stringBuilder.ToString())));
}
}
private static string specialColor = "#ffa64d";
}
public static class DeathChoiceEnable
{
[HarmonyPatch(typeof(InventoryGui), "Show")]
public static class ShowDeathChoiceUI
{
public static void Postfix(InventoryGui __instance)
{
if (ValConfig.UsePrivateKeysForDeathChoice.Value)
{
if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.PlayerHasUniqueKey(DataObjects.DeathChoiceKey))
{
return;
}
}
else if ((Object)(object)Player.m_localPlayer != (Object)null && DeathConfigurationData.playerSettings.ContainsKey(Player.m_localPlayer.GetPlayerID()))
{
return;
}
if ((Object)(object)((Component)__instance).gameObject.GetComponent<DeathChoices.DeathChoiceUI>() == (Object)null)
{
((Component)__instance).gameObject.AddComponent<DeathChoices.DeathChoiceUI>();
}
DeathChoices.DeathChoiceUI.Instance.Show();
}
}
[HarmonyPatch(typeof(InventoryGui), "Hide")]
public static class HideDeathChoiceUI
{
public static void Postfix(InventoryGui __instance)
{
DeathChoices.DeathChoiceUI.Instance.Hide();
}
}
}
public class DeathChoices
{
public class DeathChoiceUI : MonoBehaviour
{
private static DeathChoiceUI _instance;
private static GameObject DeathChoicePanel;
private static GameObject ChoicesScrollView;
private static GameObject ChoicesContent;
private static GameObject ChoicesContainer;
private static GameObject manualCloseButton;
private static GameObject selectChoiceButton;
private static Text DeathPenaltyDescription;
private static Text XPModifiersDescription;
private static Text LootModifersDescription;
private static Text HarvestModifiersDescription;
private static List<Toggle> difficultyToggles = new List<Toggle>();
private static ToggleGroup choiceGroup;
private static string selectedDeathChoice = "none";
public static DeathChoiceUI Instance => _instance ?? (_instance = new DeathChoiceUI());
public void Awake()
{
CreateStaticUIObjects();
SetChoiceList();
}
public void Show()
{
if ((Object)(object)DeathChoicePanel == (Object)null)
{
CreateStaticUIObjects();
}
DeathChoicePanel.SetActive(true);
}
public void Hide()
{
if ((Object)(object)DeathChoicePanel != (Object)null)
{
DeathChoicePanel.SetActive(false);
}
GUIManager.BlockInput(false);
}
public void MakePlayerDeathSelection()
{
if ((Object)(object)Player.m_localPlayer == (Object)null)
{
Logger.LogWarning("Player not set, ensure the local player is set.");
return;
}
if (selectedDeathChoice == "none")
{
Logger.LogWarning("No death type selected");
return;
}
Logger.LogDebug("Player selected death type " + selectedDeathChoice);
long playerID = Player.m_localPlayer.GetPlayerID();
if (DeathConfigurationData.playerSettings.ContainsKey(playerID))
{
DeathConfigurationData.playerSettings.Remove(playerID);
}
DeathConfigurationData.playerSettings.Add(playerID, new DataObjects.DeathConfiguration
{
DeathChoiceLevel = selectedDeathChoice
});
Player.m_localPlayer.AddUniqueKeyValue(DataObjects.DeathChoiceKey, selectedDeathChoice);
DeathConfigurationData.CheckAndSetPlayerDeathConfig(Player.m_localPlayer);
DeathConfigurationData.WritePlayerChoices();
Hide();
}
private void SetChoiceList()
{
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
difficultyToggles.Clear();
int num = -75;
foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> entry in DeathConfigurationData.DeathLevels)
{
GameObject obj = Object.Instantiate<GameObject>(ChoicesContainer, ChoicesContent.transform);
Transform val = obj.transform.Find("selecter");
((Component)val.Find("Label")).GetComponent<Text>().text = entry.Key;
((Component)obj.transform.Find("ChoiceName")).GetComponent<Text>().text = entry.Value.DisplayName;
Toggle component = ((Component)val).GetComponent<Toggle>();
component.group = choiceGroup;
((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate
{
((Component)DeathPenaltyDescription).GetComponent<Text>().text = entry.Value.GetDeathStyleDescription();
((Component)XPModifiersDescription).GetComponent<Text>().text = entry.Value.GetSkillModiferDescription();
((Component)LootModifersDescription).GetComponent<Text>().text = entry.Value.GetLootModifiersDescription();
((Component)HarvestModifiersDescription).GetComponent<Text>().text = entry.Value.GetResourceModiferDescription();
selectedDeathChoice = entry.Key;
});
obj.SetActive(true);
obj.transform.localPosition = new Vector3
{
x = 5f,
y = num
};
difficultyToggles.Add(component);
num -= 50;
}
}
private void CreateStaticUIObjects()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_020d: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Expected O, but got Unknown
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_0268: Unknown result type (might be due to invalid IL or missing references)
//IL_027e: Unknown result type (might be due to invalid IL or missing references)
//IL_0284: Unknown result type (might be due to invalid IL or missing references)
//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_02da: Unknown result type (might be due to invalid IL or missing references)
//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0300: Unknown result type (might be due to invalid IL or missing references)
//IL_0369: Unknown result type (might be due to invalid IL or missing references)
//IL_0378: Unknown result type (might be due to invalid IL or missing references)
//IL_0387: Unknown result type (might be due to invalid IL or missing references)
//IL_039d: Unknown result type (might be due to invalid IL or missing references)
//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0408: Unknown result type (might be due to invalid IL or missing references)
//IL_0419: Unknown result type (might be due to invalid IL or missing references)
//IL_041f: Unknown result type (might be due to invalid IL or missing references)
//IL_0488: Unknown result type (might be due to invalid IL or missing references)
//IL_0497: Unknown result type (might be due to invalid IL or missing references)
//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
//IL_0509: Unknown result type (might be due to invalid IL or missing references)
//IL_0518: Unknown result type (might be due to invalid IL or missing references)
//IL_0527: Unknown result type (might be due to invalid IL or missing references)
//IL_0538: Unknown result type (might be due to invalid IL or missing references)
//IL_053e: Unknown result type (might be due to invalid IL or missing references)
//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
//IL_05db: Unknown result type (might be due to invalid IL or missing references)
//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0628: Unknown result type (might be due to invalid IL or missing references)
//IL_0637: Unknown result type (might be due to invalid IL or missing references)
//IL_0646: Unknown result type (might be due to invalid IL or missing references)
//IL_0657: Unknown result type (might be due to invalid IL or missing references)
//IL_065d: Unknown result type (might be due to invalid IL or missing references)
//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
//IL_06e4: Unknown result type (might be due to invalid IL or missing references)
//IL_0713: Unknown result type (might be due to invalid IL or missing references)
//IL_071d: Expected O, but got Unknown
//IL_0747: Unknown result type (might be due to invalid IL or missing references)
//IL_074c: Unknown result type (might be due to invalid IL or missing references)
//IL_0771: Unknown result type (might be due to invalid IL or missing references)
//IL_078f: Unknown result type (might be due to invalid IL or missing references)
//IL_0790: Unknown result type (might be due to invalid IL or missing references)
//IL_07e0: Unknown result type (might be due to invalid IL or missing references)
//IL_07f4: Expected O, but got Unknown
//IL_0825: Unknown result type (might be due to invalid IL or missing references)
//IL_087c: Unknown result type (might be due to invalid IL or missing references)
//IL_0881: Unknown result type (might be due to invalid IL or missing references)
//IL_08da: Unknown result type (might be due to invalid IL or missing references)
//IL_08e9: Unknown result type (might be due to invalid IL or missing references)
//IL_08f8: Unknown result type (might be due to invalid IL or missing references)
//IL_090e: Unknown result type (might be due to invalid IL or missing references)
//IL_0914: Unknown result type (might be due to invalid IL or missing references)
if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
{
Logger.LogWarning("GUIManager not setup, skipping static object creation.");
return;
}
Logger.LogDebug("Creating static UI");
DeathChoicePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 800f, true);
DeathChoicePanel.SetActive(false);
((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(50f, 360f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false)).name = "DLHeader";
Text component = GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 315f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 560f, 60f, false).GetComponent<Text>();
component.resizeTextForBestFit = true;
component.resizeTextMaxSize = 20;
component.alignment = (TextAnchor)4;
manualCloseButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$close"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(360f, 360f), 60f, 60f);
Button component2 = manualCloseButton.GetComponent<Button>();
((Selectable)component2).interactable = true;
((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide));
manualCloseButton.SetActive(true);
((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 220f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "DeathPenaltyTitle";
GameObject obj = GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, 110f), GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 500f, 200f, false);
((Object)obj).name = "DeathPenaltyDesc";
DeathPenaltyDescription = obj.GetComponent<Text>();
DeathPenaltyDescription.resizeTextForBestFit = true;
DeathPenaltyDescription.resizeTextMaxSize = 18;
((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 30f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "xpModifiersTitle";
GameObject obj2 = GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_mod_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -80f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false);
((Object)obj2).name = "xpModifiersDesc";
XPModifiersDescription = obj2.GetComponent<Text>();
XPModifiersDescription.resizeTextForBestFit = true;
XPModifiersDescription.resizeTextMaxSize = 18;
((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -130f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "lootModifiersTitle";
GameObject obj3 = GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -240f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false);
((Object)obj3).name = "lootModifersDesc";
LootModifersDescription = obj3.GetComponent<Text>();
LootModifersDescription.resizeTextForBestFit = true;
LootModifersDescription.resizeTextMaxSize = 18;
((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -260f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "harvestModifiersTitle";
GameObject obj4 = GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -370f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false);
((Object)obj4).name = "harvestModifersDesc";
HarvestModifiersDescription = obj4.GetComponent<Text>();
HarvestModifiersDescription.resizeTextForBestFit = true;
HarvestModifiersDescription.resizeTextMaxSize = 18;
selectChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$deathchoice_select"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-240f, -290f), 200f, 80f);
((UnityEvent)selectChoiceButton.GetComponent<Button>().onClick).AddListener(new UnityAction(MakePlayerDeathSelection));
Logger.LogDebug("Setting up scroll entry");
ChoicesScrollView = GUIManager.Instance.CreateScrollView(DeathChoicePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 250f, 400f);
ChoicesScrollView.transform.localPosition = Vector2.op_Implicit(new Vector2
{
x = -260f,
y = -30f
});
ChoicesContent = ((Component)ChoicesScrollView.GetComponentInChildren<ContentSizeFitter>()).gameObject;
ChoicesScrollView.GetComponentInChildren<ScrollRect>().scrollSensitivity = 200f;
choiceGroup = ChoicesContent.AddComponent<ToggleGroup>();
Logger.LogDebug("Setting up death choice template entry");
ChoicesContainer = Object.Instantiate<GameObject>(new GameObject("DeathChoice"), DeathChoicePanel.transform);
RectTransform obj5 = ChoicesContainer.AddComponent<RectTransform>();
obj5.SetSizeWithCurrentAnchors((Axis)0, 100f);
obj5.SetSizeWithCurrentAnchors((Axis)1, 50f);
((Transform)obj5).position = new Vector3(0f, 0f);
ChoicesContainer.AddComponent<LayoutElement>().minHeight = 50f;
ChoicesContainer.SetActive(false);
GameObject obj6 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f);
obj6.transform.localPosition = Vector2.op_Implicit(new Vector2(10f, 0f));
((Object)obj6).name = "selecter";
((Component)obj6.transform.Find("Label")).gameObject.SetActive(false);
obj6.GetComponent<Toggle>().isOn = false;
((Object)GUIManager.Instance.CreateText("Name", ChoicesContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(200f, 0f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 350f, 40f, false)).name = "ChoiceName";
}
}
}
public static class DeathProgressionSkill
{
[HarmonyPatch(typeof(Player), "RaiseSkill")]
public class Deathskill_EXP_Patch
{
public static void Postfix(Player __instance)
{
//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
timeSinceGameStart += Time.deltaTime;
if (lastSkillIncreaseTickTime == 0f)
{
lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value;
PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
_bossKills = playerProfile.m_playerStats.m_stats[(PlayerStatType)85];
_enemykills = playerProfile.m_playerStats.m_stats[(PlayerStatType)6];
_piecesBuilt = playerProfile.m_playerStats.m_stats[(PlayerStatType)2];
_treesChopped = playerProfile.m_playerStats.m_stats[(PlayerStatType)27];
_mineAmount = playerProfile.m_playerStats.m_stats[(PlayerStatType)38];
_craftAndUpgrades = playerProfile.m_playerStats.m_stats[(PlayerStatType)1];
}
if (timeSinceGameStart > lastSkillIncreaseTickTime)
{
lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value;
PlayerProfile playerProfile2 = Game.instance.GetPlayerProfile();
float num = playerProfile2.m_playerStats.m_stats[(PlayerStatType)85];
float num2 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)6];
float num3 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)2];
float num4 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)27];
float num5 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)38];
float num6 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)1];
float num7 = 0f;
float num8 = 0f;
float num9 = 0f;
float num10 = 0f;
float num11 = 0f;
float num12 = 0f;
if (num > _bossKills || num2 > _enemykills)
{
num12 = (num - _bossKills) * ValConfig.SkillGainOnBossKills.Value;
num11 = (num2 - _enemykills) * ValConfig.SkillGainOnKills.Value;
Logger.LogDebug($"DeathProgression kill skill bosskill: {num12} kill: {num11}");
_bossKills = num;
_enemykills = num2;
}
if (num3 > _piecesBuilt)
{
num10 = (num3 - _piecesBuilt) * ValConfig.SkillGainOnBuilding.Value;
Logger.LogDebug($"DeathProgression building skill: {num10}");
_piecesBuilt = num3;
}
if (num4 > _treesChopped || num5 > _mineAmount)
{
num9 = (num4 - _treesChopped) * ValConfig.SkillGainOnResourceGathering.Value;
num8 = (num5 - _mineAmount) * ValConfig.SkillGainOnResourceGathering.Value;
Logger.LogDebug($"DeathProgression harvesting skill tree_harvest: {num9} mining: {num8}");
_treesChopped = num4;
_mineAmount = num5;
}
if (num6 > _craftAndUpgrades)
{
num7 = (num6 - _craftAndUpgrades) * ValConfig.SkillGainOnCrafts.Value;
Logger.LogDebug($"DeathProgression crafting skill crafting: {num7}");
_craftAndUpgrades = num6;
}
float num13 = num12 + num11 + num10 + num10 + num9 + num8 + num7;
float num14 = (float)Math.Log(__instance.m_timeSinceDeath) / 5f * 0.5f;
float num15 = num14 * num13;
if (Deathlink.RustyAlmanacClassesLoaded)
{
int num16 = Mathf.RoundToInt(num15 * ValConfig.AlmanacClassesXPGainScale.Value);
Logger.LogDebug($"Almanac XP Gain {num16}");
ClassesAPI.AddEXP(num16);
}
if (Deathlink.WackyMMOLoaded)
{
int num17 = Mathf.RoundToInt(num15 * ValConfig.WackyMMOXPGainScale.Value);
Logger.LogDebug($"WackyMMO XP Gain {num17}");
EpicMMOSystem_API.AddExp(num17);
}
Logger.LogDebug($"DeathProgression skill bonus from survival (survive time: {__instance.m_timeSinceDeath}) {num14} x {num13} = {num15}");
((Character)Player.m_localPlayer).RaiseSkill(DeathSkill, num15);
}
}
}
public static SkillType DeathSkill;
private static float lastSkillIncreaseTickTime;
private static float timeSinceGameStart;
private static float _bossKills;
private static float _enemykills;
private static float _piecesBuilt;
private static float _mineAmount;
private static float _treesChopped;
private static float _craftAndUpgrades;
public static void SetupDeathSkill()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
SkillConfig val = new SkillConfig();
val.Name = LocalizationManager.Instance.TryTranslate("$death_skill");
val.Description = LocalizationManager.Instance.TryTranslate("$death_skill_description");
val.Icon = Deathlink.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/death_skill.png");
val.Identifier = "midnightsfx.deathskill";
val.IncreaseStep = 0.1f;
DeathSkill = SkillManager.Instance.AddSkill(val);
if (!SkillsChanges.skills_to_avoid_standard_death_penalty.Contains(DeathSkill))
{
SkillsChanges.skills_to_avoid_standard_death_penalty.Add(DeathSkill);
}
}
public static float DeathSkillCalculatePercentWithBonus(float bonus = 0f, float min = 0.01f, float max = 1f)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
float num = 0f;
if ((Object)(object)Player.m_localPlayer != (Object)null)
{
float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(DeathSkill);
num += skillFactor;
}
num += bonus;
if (num < min)
{
num = min;
}
if (num > max)
{
num = max;
}
return num;
}
}
public static class HarvestModifiers
{
[HarmonyPatch(typeof(TreeLog), "Destroy")]
public static class IncreaseDropsFromTree
{
private static void Postfix(TreeLog __instance, HitData hitData)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hitData != null && (Object)(object)Player.m_localPlayer != (Object)null && hitData.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
{
IncreaseDrops(__instance.m_dropWhenDestroyed, ((Component)__instance).transform.position);
}
}
}
[HarmonyPatch(typeof(Pickable), "Drop")]
public static class IncreaseDropsPickable
{
private static void Prefix(Pickable __instance, GameObject prefab, int offset)
{
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
if (Deathlink.pcfg().ResourceModifiers == null || Deathlink.pcfg().ResourceModifiers.Count <= 0 || !((Object)(object)Player.m_localPlayer != (Object)null))
{
return;
}
float num = Deathlink.pcfg().GetResouceEarlyCache(prefab.gameObject) - 1f;
int num2 = 0;
while (num > 0f)
{
float value = Random.value;
Logger.LogDebug($"Checking to increase drops {value} <= {num}");
if (value <= num)
{
num2++;
}
num -= 1f;
}
if (num2 > 0)
{
Vector2 val = Random.insideUnitCircle * 0.2f;
Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * __instance.m_spawnOffset + new Vector3(val.x, 0.5f * (float)offset, val.y);
Quaternion val3 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
for (int i = 0; i < num2; i++)
{
Object.Instantiate<GameObject>(prefab, val2, val3);
}
}
}
}
[HarmonyPatch(typeof(MineRock5), "RPC_SetAreaHealth")]
public static class Minerock5DestroyPatch
{
private static void Postfix(MineRock5 __instance, long sender, int index, float health)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && (Object)(object)Player.m_localPlayer != (Object)null && health <= 0f)
{
IncreaseDrops(__instance.m_dropItems, ((Component)__instance).gameObject.transform.position);
}
}
}
[HarmonyPatch(typeof(Destructible), "Destroy")]
public static class IncreaseDropsFromDestructible
{
private static void Prefix(Destructible __instance, HitData hit)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())
{
IncreaseDestructibleDrops(__instance);
}
}
public static void IncreaseDestructibleDrops(Destructible destructible)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)destructible.m_spawnWhenDestroyed != (Object)null))
{
Vector3 position = ((Component)destructible).transform.position;
DropOnDestroyed component = ((Component)destructible).GetComponent<DropOnDestroyed>();
if (!((Object)(object)component == (Object)null) && component.m_dropWhenDestroyed != null)
{
IncreaseDrops(component.m_dropWhenDestroyed, position);
}
}
}
}
public static void IncreaseDrops(DropTable drops, Vector3 position)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollHarvestLoot();
if (list2.Count > 0)
{
list.AddRange(list2);
}
int num = Random.Range(drops.m_dropMin, drops.m_dropMax);
int num2 = drops.m_drops.Count;
if (num == 0)
{
num = 1;
}
if (num2 == 0)
{
num2 = 1;
}
int num3 = Mathf.RoundToInt((float)(num / num2));
foreach (DropData drop in drops.m_drops)
{
float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(drop.m_item);
if (resouceEarlyCache != 1f)
{
int num4 = Mathf.RoundToInt((float)num3 * resouceEarlyCache);
if (num4 > 0)
{
list.Add(new KeyValuePair<GameObject, int>(drop.m_item, num4));
}
}
}
if (list.Count <= 0)
{
return;
}
Logger.LogDebug("Deathlink drop increase.");
foreach (KeyValuePair<GameObject, int> item in list)
{
Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
int maxStackSize = item.Key.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
int num5 = item.Value;
if (num5 > maxStackSize)
{
int num6 = num5 / maxStackSize;
for (int i = 0; i < num6; i++)
{
Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = maxStackSize;
Logger.LogDebug($"Dropping {maxStackSize} of {((Object)item.Key).name} to the world.");
}
num5 -= maxStackSize * num6;
}
Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = num5;
Logger.LogDebug($"Dropping {num5} of {((Object)item.Key).name} to the world.");
}
}
}
public static class LootModifiers
{
[HarmonyPatch(typeof(CharacterDrop))]
public static class CalculateLootByModifiers
{
[HarmonyPostfix]
[HarmonyPatch("GenerateDropList")]
private static void Postfix(List<KeyValuePair<GameObject, int>> __result, CharacterDrop __instance)
{
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
if (!__instance.m_character.m_localPlayerHasHit || Deathlink.pcfg().DeathLootModifiers == null || Deathlink.pcfg().DeathLootModifiers.Count == 0)
{
return;
}
List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
foreach (KeyValuePair<GameObject, int> item in __result)
{
float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(((Object)item.Key).name);
if (resouceEarlyCache == 1f)
{
list.Add(item);
continue;
}
int num = Mathf.RoundToInt((float)item.Value * resouceEarlyCache);
if (num >= 1)
{
list.Add(new KeyValuePair<GameObject, int>(item.Key, num));
}
}
List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollKillLoot();
if (list2.Count > 0)
{
foreach (KeyValuePair<GameObject, int> item2 in list2)
{
for (int i = 0; i < item2.Value; i++)
{
Object.Instantiate<GameObject>(item2.Key, ((Component)__instance).transform.position, Quaternion.identity);
}
}
}
__result = list;
}
}
}
public static class SkillsChanges
{
[HarmonyPatch(typeof(Skills), "OnDeath")]
private static class OnDeath_Patch
{
private static bool Prefix(Skills __instance)
{
if (((Character)__instance.m_player).m_seman.HaveStatusEffect(SEMan.s_statusEffectSoftDeath))
{
return false;
}
if (Deathlink.pcfg().DeathStyle.skillLossOnDeath)
{
float num = Mathf.Lerp(Deathlink.pcfg().DeathStyle.maxSkillLossPercentage, Deathlink.pcfg().DeathStyle.minSkillLossPercentage, DeathProgressionSkill.DeathSkillCalculatePercentWithBonus());
Logger.LogDebug($"{num}");
LowerConfigurableSkills(__instance, num);
}
return false;
}
private static void LowerConfigurableSkills(Skills skills, float factor)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
foreach (KeyValuePair<SkillType, Skill> skillDatum in skills.m_skillData)
{
if (skills_to_avoid_standard_death_penalty.Contains(skillDatum.Key))
{
Logger.LogDebug($"Skipping lowering skill {skillDatum.Key} current level: {skillDatum.Value.m_level}");
continue;
}
float num = skillDatum.Value.m_level * factor;
Skill value = skillDatum.Value;
value.m_level -= num;
skillDatum.Value.m_accumulator = 0f;
}
if (Deathlink.RustyAlmanacClassesLoaded && ValConfig.EnableAlmanacClassesXPLossOnDeath.Value)
{
int level = ClassesAPI.GetLevel();
int num2 = Mathf.RoundToInt((float)level * factor * 500f * ValConfig.AlmanacClassesXPLossScale.Value) * -1;
Logger.LogDebug($"Almanac (lvl {level}) XP Loss: {num2}");
ClassesAPI.AddEXP(num2);
}
if (Deathlink.WackyMMOLoaded && ValConfig.EnableWackyMMOXPLossOnDeath.Value)
{
int level2 = EpicMMOSystem_API.GetLevel();
int num3 = Mathf.RoundToInt((float)level2 * factor * 500f * ValConfig.WackyMMOXPLossScale.Value) * -1;
Logger.LogDebug($"WackyMMO (lvl {level2}) XP Loss: {num3}");
EpicMMOSystem_API.AddExp(num3);
}
Player localPlayer = Player.m_localPlayer;
if (localPlayer != null)
{
((Character)localPlayer).Message((MessageType)1, "$msg_skills_lowered", 0, (Sprite)null);
}
}
}
[HarmonyPatch(typeof(Skills), "RaiseSkill")]
private static class SkillRaisePatch
{
private static void Prefix(Skills __instance, SkillType skillType, float factor)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
float skillBonusLazyCache = Deathlink.pcfg().GetSkillBonusLazyCache(skillType);
Logger.LogDebug($"{skillType} skillGain Modified {skillBonusLazyCache}");
if (skillBonusLazyCache != 0f)
{
factor *= skillBonusLazyCache;
}
}
}
public static List<SkillType> skills_to_avoid_standard_death_penalty = new List<SkillType>();
}
public static class OnDeathChanges
{
[HarmonyPatch(typeof(Player))]
public static class OnDeath_Tombstone_Patch
{
[HarmonyTranspiler]
[HarmonyPatch("OnDeath")]
private static IEnumerable<CodeInstruction> ConstructorTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(instructions, generator);
val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Player), "CreateTombStone", (Type[])null, (Type[])null), (string)null)
}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<Player>>((Action<Player>)ModifyDeath) })
.CreateLabelOffset(out var label, 4)
.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Br, (object)label)
})
.ThrowIfNotMatch("Unable to patch Deathlink player death changes.", Array.Empty<CodeMatch>());
return val.Instructions();
}
private static void ModifyDeath(Player __instance)
{
TombstoneOnDeath(__instance);
FoodLossOnDeath(__instance);
}
public static void FoodLossOnDeath(Player instance)
{
if (!Deathlink.pcfg().DeathStyle.foodLossOnDeath)
{
return;
}
if (Deathlink.pcfg().DeathStyle.foodLossUsesDeathlink && instance.m_foods.Count > 0)
{
float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus();
if (num >= 0.9f)
{
return;
}
if (num >= 0.6f && num < 0.9f)
{
instance.m_foods.Remove(instance.m_foods[0]);
}
else if (num > 0.3f && num < 0.6f)
{
instance.m_foods.Remove(instance.m_foods[0]);
if (instance.m_foods.Count > 0)
{
instance.m_foods.Remove(instance.m_foods[0]);
}
}
else
{
instance.m_foods.Clear();
}
}
else
{
instance.m_foods.Clear();
}
}
public static void TombstoneOnDeath(Player instance)
{
//IL_0366: Unknown result type (might be due to invalid IL or missing references)
//IL_0376: Unknown result type (might be due to invalid IL or missing references)
//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
//IL_04df: Unknown result type (might be due to invalid IL or missing references)
//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
List<ItemData> allItems = ((Humanoid)instance).m_inventory.GetAllItems();
List<ItemData> list = new List<ItemData>();
List<ItemData> list2 = new List<ItemData>();
Inventory inventory = ((Humanoid)instance).m_inventory;
Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>>();
string[] source = ValConfig.ItemsNotSkillChecked.Value.Split(new char[1] { ',' });
foreach (ItemData item in allItems)
{
if ((Object)(object)item.m_dropPrefab != (Object)null && source.Contains(((Object)item.m_dropPrefab).name))
{
list2.Add(item);
}
else
{
list.Add(item);
}
}
switch (Deathlink.pcfg().DeathStyle.itemLossStyle)
{
case DataObjects.ItemLossStyle.None:
Logger.LogDebug("No items destroyed on death.");
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemSaved, list);
break;
case DataObjects.ItemLossStyle.DestroyNonWeaponArmor:
Logger.LogDebug("Destroying non Equipment items.");
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list.GetNotEquipment());
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, list.GetEquipment());
foreach (ItemData item2 in list.GetNotEquipment())
{
((Humanoid)instance).m_inventory.RemoveItem(item2);
}
if (!Deathlink.AzuEPILoaded)
{
break;
}
Logger.LogDebug("AzuEPI| Removing non-equipment items from quickslots.");
foreach (ItemData quickSlotsItem in API.GetQuickSlotsItems())
{
if (!quickSlotsItem.IsEquipment())
{
((Humanoid)instance).m_inventory.RemoveItem(quickSlotsItem);
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, quickSlotsItem);
}
else
{
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, quickSlotsItem);
}
}
break;
case DataObjects.ItemLossStyle.DestroyAll:
Logger.LogDebug("Destroying all non skill checked items.");
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list);
foreach (ItemData item3 in list)
{
((Humanoid)instance).m_inventory.RemoveItem(item3);
}
if (Deathlink.AzuEPILoaded)
{
Logger.LogDebug("AzuEPI| Destroying quickslot items.");
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, API.GetQuickSlotsItems());
API.GetQuickSlotsItems().ForEach(delegate(ItemData item)
{
((Humanoid)instance).m_inventory.RemoveItem(item);
});
}
break;
case DataObjects.ItemLossStyle.DeathlinkBased:
Logger.LogDebug("Destroying random items based on deathlink skill");
dictionary = DetermineItemResultsByDeathlink(instance, list);
dictionary[DataObjects.ItemResults.EquipmentLost].ForEach(delegate(ItemData item)
{
((Humanoid)instance).m_inventory.RemoveItem(item);
});
dictionary[DataObjects.ItemResults.ItemLost].ForEach(delegate(ItemData item)
{
((Humanoid)instance).m_inventory.RemoveItem(item);
});
break;
}
if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Destroy)
{
Logger.LogDebug("Non skill checked being destroyed.");
dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list2);
}
if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Save)
{
Logger.LogDebug("Non skill checked items being left on player.");
}
if ((!dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) || dictionary[DataObjects.ItemResults.EquipmentSaved].Count <= 0) && (!dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) || dictionary[DataObjects.ItemResults.ItemSaved].Count <= 0) && (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction != DataObjects.NonSkillCheckedItemAction.Tombstone || list2.Count() <= 0))
{
return;
}
Logger.LogDebug("Tombstone needed");
GameObject obj = Object.Instantiate<GameObject>(instance.m_tombstone, ((Character)instance).GetCenterPoint(), ((Component)instance).transform.rotation);
Inventory inventory2 = obj.GetComponent<Container>().GetInventory();
if (Deathlink.pcfg().DeathStyle.itemSavedStyle == DataObjects.ItemSavedStyle.Tombstone)
{
Logger.LogDebug("Adding saved items to tombstone.");
if (dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) && dictionary[DataObjects.ItemResults.EquipmentSaved].Count > 0)
{
AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.EquipmentSaved]);
dictionary[DataObjects.ItemResults.EquipmentSaved].ForEach(delegate(ItemData item)
{
((Humanoid)instance).m_inventory.RemoveItem(item);
});
}
if (dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) && dictionary[DataObjects.ItemResults.ItemSaved].Count > 0)
{
AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.ItemSaved]);
dictionary[DataObjects.ItemResults.ItemSaved].ForEach(delegate(ItemData item)
{
((Humanoid)instance).m_inventory.RemoveItem(item);
});
}
}
if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Tombstone)
{
Logger.LogDebug("Adding saved non-skill checked items to tombstone.");
AddItemsToTombstone(inventory2, list2);
list2.ForEach(delegate(ItemData item)
{
((Humanoid)instance).m_inventory.RemoveItem(item);
});
}
TombStone component = obj.GetComponent<TombStone>();
PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
string name = playerProfile.GetName();
long playerID = playerProfile.GetPlayerID();
component.Setup(name, playerID);
inventory.Changed();
if (ValConfig.ShowDeathMapMarker.Value)
{
Minimap.instance.AddPin(((Component)instance).transform.position, (PinType)4, $"$hud_mapday {EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds())}", true, false, 0L, default(PlatformUserID));
}
}
public static void AddItemsToTombstone(Inventory tombstone, List<ItemData> transferItems)
{
int num = Mathf.RoundToInt(Mathf.Sqrt((float)transferItems.Count())) + 1;
tombstone.m_width += num;
tombstone.m_height += num;
foreach (ItemData transferItem in transferItems)
{
tombstone.m_inventory.Add(transferItem);
}
tombstone.Changed();
}
internal static Dictionary<DataObjects.ItemResults, List<ItemData>> DetermineItemResultsByDeathlink(Player player, List<ItemData> playerItemsWithoutNonSkillCheckedItems)
{
float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus();
int num2 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxItemsKept - Deathlink.pcfg().DeathStyle.minItemsKept) * num + (float)Deathlink.pcfg().DeathStyle.minItemsKept);
int num3 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxEquipmentKept - Deathlink.pcfg().DeathStyle.minEquipmentKept) * num + (float)Deathlink.pcfg().DeathStyle.minEquipmentKept);
int remainingsaves = num2 + num3;
Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>>
{
{
DataObjects.ItemResults.EquipmentSaved,
new List<ItemData>()
},
{
DataObjects.ItemResults.EquipmentLost,
new List<ItemData>()
},
{
DataObjects.ItemResults.ItemSaved,
new List<ItemData>()
},
{
DataObjects.ItemResults.ItemLost,
new List<ItemData>()
}
};
int equipment_saved_count = 0;
foreach (ItemData item in Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetEquipment()))
{
if (remainingsaves > 0)
{
if (RemoveEquipmentByStyle(equipment_saved_count, num3, item, remainingsaves, out remainingsaves, out equipment_saved_count))
{
Logger.LogDebug("Save: " + item.m_shared.m_name);
dictionary[DataObjects.ItemResults.EquipmentSaved].Add(item);
}
else
{
Logger.LogDebug("Remove by style: " + item.m_shared.m_name);
dictionary[DataObjects.ItemResults.EquipmentLost].Add(item);
}
}
else
{
Logger.LogDebug("Save limit reached, removing: " + item.m_shared.m_name);
dictionary[DataObjects.ItemResults.EquipmentLost].Add(item);
}
}
if (Deathlink.AzuEPILoaded)
{
foreach (ItemData quickSlotsItem in API.GetQuickSlotsItems())
{
if (quickSlotsItem.IsEquipment() && remainingsaves > 0)
{
remainingsaves--;
num2--;
dictionary[DataObjects.ItemResults.EquipmentSaved].Add(quickSlotsItem);
}
else if (remainingsaves > 0)
{
remainingsaves--;
num2--;
dictionary[DataObjects.ItemResults.ItemSaved].Add(quickSlotsItem);
}
else
{
dictionary[DataObjects.ItemResults.ItemLost].Add(quickSlotsItem);
}
}
}
List<ItemData> list = Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetNotEquipment());
if (remainingsaves > 0)
{
foreach (ItemData item2 in list)
{
if (remainingsaves > 0 && num2 > 0)
{
Logger.LogDebug("NonEq| Saving: " + item2.m_shared.m_name);
dictionary[DataObjects.ItemResults.ItemSaved].Add(item2);
remainingsaves--;
num2--;
}
else
{
Logger.LogDebug("NonEq| Removing: " + item2.m_shared.m_name);
dictionary[DataObjects.ItemResults.ItemLost].Add(item2);
}
}
}
else
{
Logger.LogDebug($"NonEq| Removing: {list.Count} due to no saves remaining.");
foreach (ItemData item3 in list)
{
dictionary[DataObjects.ItemResults.ItemLost].Add(item3);
}
}
return dictionary;
}
internal static bool RemoveEquipmentByStyle(int equipment_saved, int max_equipment_savable, ItemData equipment, int numberOfItemsSavable, out int remainingsaves, out int equipment_saved_count)
{
equipment_saved_count = 0;
remainingsaves = 0;
if (numberOfItemsSavable <= 0)
{
return false;
}
if (equipment_saved >= max_equipment_savable)
{
Logger.LogDebug($"Max equipment retained ({max_equipment_savable}) reached, removing {((Object)equipment.m_dropPrefab).name}");
return false;
}
Logger.LogDebug($"Saving equipment remaining savable?({numberOfItemsSavable}) {((Object)equipment.m_dropPrefab).name}");
equipment_saved_count = equipment_saved + 1;
remainingsaves = numberOfItemsSavable - 1;
return true;
}
}
}
}
namespace Deathlink.Common
{
internal static class TerminalCommands
{
internal class ResetPlayerDeathChoice : ConsoleCommand
{
public override string Name => "DL-RESET-CHOICE";
public override bool IsNetwork => true;
public override string Help => "Format: [steamID|playerName] resets the deathlink choice for the target player. Accepts a platform Steam ID or a case-insensitive player name.";
public override void Run(string[] args)
{
//IL_0043: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Expected O, but got Unknown
if (!SynchronizationManager.Instance.PlayerIsAdmin)
{
Logger.LogWarning("You are not an admin, and not allowed to run this command.");
return;
}
if (args.Length < 1)
{
Logger.LogInfo("Player Steam ID or name required");
return;
}
string text = args[0];
foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
{
string text2 = player.m_userInfo.m_id.m_userID.ToString();
string displayName = player.m_userInfo.m_displayName;
bool flag = text2 == text;
bool flag2 = string.Equals(displayName, text, StringComparison.OrdinalIgnoreCase);
bool flag3 = string.Equals(player.m_name, text, StringComparison.OrdinalIgnoreCase);
Logger.LogDebug("Checking Player " + displayName + " (platformID: " + text2 + ", playerName: " + player.m_name + ") against '" + text + "'");
if (flag || flag2 || flag3)
{
Logger.LogInfo("Matched player " + displayName + " (platformID: " + text2 + ") for reset command.");
ZPackage val = new ZPackage();
val.Write(text2);
Logger.LogDebug("Requesting server reset of player saved Deathlink choice");
ValConfig.resetChoiceRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val);
}
}
}
}
internal static void AddCommands()
{
CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ResetPlayerDeathChoice());
}
}
public class DataObjects
{
public enum ItemLossStyle
{
None,
DestroyNonWeaponArmor,
DeathlinkBased,
DestroyAll
}
public enum ItemResults
{
EquipmentSaved,
EquipmentLost,
ItemSaved,
ItemLost
}
public enum ItemSavedStyle
{
OnCharacter,
Tombstone
}
public enum ResourceGainTypes
{
Kills,
Harvesting
}
public enum NonSkillCheckedItemAction
{
Destroy,
Tombstone,
Save
}
public class DeathProgressionDetails
{
public bool foodLossOnDeath = true;
public bool foodLossUsesDeathlink = true;
public int minItemsKept;
public int maxItemsKept;
public int minEquipmentKept;
public int maxEquipmentKept;
public bool skillLossOnDeath = true;
public float maxSkillLossPercentage;
public float minSkillLossPercentage;
public ItemLossStyle itemLossStyle;
public ItemSavedStyle itemSavedStyle;
public NonSkillCheckedItemAction nonSkillCheckedItemAction = NonSkillCheckedItemAction.Tombstone;
}
public class DeathResourceModifier
{
public bool skillInfluence { get; set; } = true;
public List<string> prefabs { get; set; }
public float bonusModifer { get; set; }
public List<ResourceGainTypes> bonusActions { get; set; }
}
public class DeathSkillModifier
{
public bool skillInfluence { get; set; } = true;
public SkillType skill { get; set; }
public float bonusModifer { get; set; }
}
public class DeathLootModifier
{
private bool skillInfluence { get; set; } = true;
public string prefab { get; set; }
public float chance { get; set; }
public int amount { get; set; } = 1;
public List<ResourceGainTypes> bonusActions { get; set; }
}
public class DeathChoiceLevel
{
private Dictionary<SkillType, float> CalculatedSkillMods = new Dictionary<SkillType, float>();
private Dictionary<string, float> CalculatedResourceMods = new Dictionary<string, float>();
private bool CalculatedResourceModsCached;
private Dictionary<GameObject, Tuple<float, int>> KillLootModifiers = new Dictionary<GameObject, Tuple<float, int>>();
private bool CalculatedKillLootModifiersCached;
private Dictionary<GameObject, Tuple<float, int>> ResourceLootModifiers = new Dictionary<GameObject, Tuple<float, int>>();
private bool CalculatedHarvestLootModifiersCached;
public string DisplayName { get; set; }
public DeathProgressionDetails DeathStyle { get; set; }
public float DeathSkillRate { get; set; } = 1f;
public Dictionary<string, DeathResourceModifier> ResourceModifiers { get; set; }
public Dictionary<string, DeathSkillModifier> SkillModifiers { get; set; }
public Dictionary<string, DeathLootModifier> DeathLootModifiers { get; set; }
public List<KeyValuePair<GameObject, int>> RollKillLoot()
{
if (!CalculatedKillLootModifiersCached)
{
if (DeathLootModifiers != null && DeathLootModifiers.Count > 0)
{
foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers)
{
if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Kills))
{
GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab);
if ((Object)(object)prefab == (Object)null)
{
Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building kill loot table, it will be skipped.");
}
else
{
KillLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount));
}
}
}
}
CalculatedKillLootModifiersCached = true;
}
List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
foreach (KeyValuePair<GameObject, Tuple<float, int>> killLootModifier in KillLootModifiers)
{
float value = Random.value;
Logger.LogDebug($"Rolling chance loot for: {((Object)killLootModifier.Key.gameObject).name} {value} < {killLootModifier.Value.Item1}");
if (value < killLootModifier.Value.Item1)
{
list.Add(new KeyValuePair<GameObject, int>(killLootModifier.Key, killLootModifier.Value.Item2));
}
}
return list;
}
public List<KeyValuePair<GameObject, int>> RollHarvestLoot()
{
if (!CalculatedHarvestLootModifiersCached)
{
if (DeathLootModifiers != null && DeathLootModifiers.Count > 0)
{
foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers)
{
if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Harvesting))
{
GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab);
if ((Object)(object)prefab == (Object)null)
{
Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building harvest loot table, it will be skipped.");
}
else
{
ResourceLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount));
}
}
}
}
CalculatedHarvestLootModifiersCached = true;
}
List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>();
foreach (KeyValuePair<GameObject, Tuple<float, int>> resourceLootModifier in ResourceLootModifiers)
{
if (Random.value < resourceLootModifier.Value.Item1)
{
list.Add(new KeyValuePair<GameObject, int>(resourceLootModifier.Key, resourceLootModifier.Value.Item2));
}
}
return list;
}
public float GetResouceEarlyCache(string prefab)
{
if (!CalculatedResourceModsCached)
{
Logger.LogDebug("Building cache entry for " + prefab);
if (ResourceModifiers != null)
{
foreach (KeyValuePair<string, DeathResourceModifier> resourceModifier in ResourceModifiers)
{
if (resourceModifier.Value.prefabs == null)
{
continue;
}
foreach (string prefab2 in resourceModifier.Value.prefabs)
{
Logger.LogDebug($"Building cache entry for {prefab2} - {resourceModifier.Value.bonusModifer}");
CalculatedResourceMods.Add(prefab2, resourceModifier.Value.bonusModifer);
}
}
}
CalculatedResourceModsCached = true;
}
if (CalculatedResourceMods.ContainsKey(prefab))
{
return CalculatedResourceMods[prefab];
}
return 1f;
}
public float GetResouceEarlyCache(GameObject prefab)
{
if ((Object)(object)prefab == (Object)null)
{
return 1f;
}
return GetResouceEarlyCache(((Object)prefab).name);
}
public float GetSkillBonusLazyCache(SkillType skilltype)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Invalid comparison between Unknown and I4
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
if (CalculatedSkillMods.TryGetValue(skilltype, out var value))
{
return value;
}
float num = 0f;
if (SkillModifiers != null && SkillModifiers.Count > 0)
{
foreach (KeyValuePair<string, DeathSkillModifier> skillModifier in SkillModifiers)
{
if ((int)skillModifier.Value.skill == 999 || skillModifier.Value.skill == skilltype)
{
num += skillModifier.Value.bonusModifer;
}
}
}
CalculatedSkillMods.Add(skilltype, num);
return num;
}
public string GetLootModifiersDescription()
{
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers)
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("<color={0}>{1}%</color> $loot_desc_pt1 {2} $loot_desc_pt2 {3}", "#b9f2ff", deathLootModifier.Value.chance * 100f, deathLootModifier.Key, string.Join(",", deathLootModifier.Value.bonusActions))));
}
return stringBuilder.ToString();
}
public string GetSkillModiferDescription()
{
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, DeathSkillModifier> skillModifier in SkillModifiers)
{
if (skillModifier.Value.bonusModifer > 1f)
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} +<color={1}>{2}%</color> $xp", skillModifier.Key, "#b9f2ff", Mathf.Round((skillModifier.Value.bonusModifer - 1f) * 100f))));
}
else
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} -<color={1}>{2}%</color> $xp", skillModifier.Key, "#ff4040", Mathf.Round((1f - skillModifier.Value.bonusModifer) * 100f))));
}
}
return stringBuilder.ToString();
}
public string GetResourceModiferDescription()
{
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, DeathResourceModifier> resourceModifier in ResourceModifiers)
{
if (resourceModifier.Value.bonusModifer > 1f)
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} $drops <color={1}>{2}%</color> $more {3}", resourceModifier.Key, "#b9f2ff", (resourceModifier.Value.bonusModifer - 1f) * 100f, string.Join(",", resourceModifier.Value.bonusActions))));
}
else
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} $drops <color={1}{2}%</color> $less {3}", resourceModifier.Key, "#ff4040", (1f - resourceModifier.Value.bonusModifer) * 100f, string.Join(",", resourceModifier.Value.bonusActions))));
}
}
return stringBuilder.ToString();
}
public string GetDeathStyleDescription()
{
StringBuilder stringBuilder = new StringBuilder();
switch (DeathStyle.itemLossStyle)
{
case ItemLossStyle.None:
stringBuilder.AppendLine(Localization.instance.Localize("$no_item_loss"));
break;
case ItemLossStyle.DestroyNonWeaponArmor:
stringBuilder.AppendLine(Localization.instance.Localize("$no_equipment_loss"));
break;
case ItemLossStyle.DestroyAll:
stringBuilder.AppendLine(Localization.instance.Localize("$all_item_loss"));
break;
case ItemLossStyle.DeathlinkBased:
stringBuilder.AppendLine(Localization.instance.Localize("$limited_saved_deathlink"));
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$equipment_kept <color={0}>{1}</color> - <color={2}>{3}</color>", "#b9f2ff", DeathStyle.minEquipmentKept, "#b9f2ff", DeathStyle.maxEquipmentKept)));
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$items_kept <color={0}>{1}</color> - <color={2}>{3}</color>", "#b9f2ff", DeathStyle.minItemsKept, "#b9f2ff", DeathStyle.maxItemsKept)));
break;
}
if (DeathStyle.itemLossStyle != ItemLossStyle.DestroyAll)
{
if (DeathStyle.itemSavedStyle == ItemSavedStyle.OnCharacter)
{
stringBuilder.AppendLine(Localization.instance.Localize("$saved_to_character"));
}
else
{
stringBuilder.AppendLine(Localization.instance.Localize("$saved_to_tombstone"));
}
if (DeathStyle.nonSkillCheckedItemAction == NonSkillCheckedItemAction.Tombstone)
{
stringBuilder.AppendLine(Localization.instance.Localize("$non_skill_items_tombstone"));
}
if (DeathStyle.nonSkillCheckedItemAction == NonSkillCheckedItemAction.Save)
{
stringBuilder.AppendLine(Localization.instance.Localize("$non_skill_items_character"));
}
if (DeathStyle.nonSkillCheckedItemAction == NonSkillCheckedItemAction.Destroy)
{
stringBuilder.AppendLine(Localization.instance.Localize("$non_skill_items_destroy"));
}
}
if (DeathStyle.foodLossOnDeath)
{
if (DeathStyle.foodLossUsesDeathlink)
{
stringBuilder.AppendLine(Localization.instance.Localize("$food_loss_deathlink"));
}
else
{
stringBuilder.AppendLine(Localization.instance.Localize("$food_loss"));
}
}
if (DeathStyle.maxSkillLossPercentage == DeathStyle.minSkillLossPercentage)
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$skill_loss_desc <color={0}>{1}%</color>", "#ff4040", DeathStyle.maxSkillLossPercentage * 100f)));
}
else
{
stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$skill_loss_desc <color={0}>{1}%</color> - <color={2}>{3}%</color> $influenced_by_deathlink", "#ff4040", DeathStyle.maxSkillLossPercentage * 100f, "#ff4040", DeathStyle.minSkillLossPercentage * 100f)));
}
return stringBuilder.ToString();
}
}
public class DeathConfiguration
{
public string DeathChoiceLevel { get; set; }
}
public class PlayerDeathConfiguration
{
public Dictionary<long, DeathConfiguration> selectedDeathStyle { get; set; }
}
public abstract class ZNetProperty<T>
{
protected readonly ZNetView zNetView;
public string Key { get; private set; }
public T DefaultValue { get; private set; }
protected ZNetProperty(string key, ZNetView zNetView, T defaultValue)
{
Key = key;
DefaultValue = defaultValue;
this.zNetView = zNetView;
}
private void ClaimOwnership()
{
if (!zNetView.IsOwner())
{
zNetView.ClaimOwnership();
}
}
public void Set(T value)
{
SetValue(value);
}
public void ForceSet(T value)
{
ClaimOwnership();
Set(value);
}
public abstract T Get();
protected abstract void SetValue(T value);
}
public class BoolZNetProperty : ZNetProperty<bool>
{
public BoolZNetProperty(string key, ZNetView zNetView, bool defaultValue)
: base(key, zNetView, defaultValue)
{
}
public override bool Get()
{
return zNetView.GetZDO().GetBool(base.Key, base.DefaultValue);
}
protected override void SetValue(bool value)
{
zNetView.GetZDO().Set(base.Key, value);
}
}
public class IntZNetProperty : ZNetProperty<int>
{
public IntZNetProperty(string key, ZNetView zNetView, int defaultValue)
: base(key, zNetView, defaultValue)
{
}
public override int Get()
{
return zNetView.GetZDO().GetInt(base.Key, base.DefaultValue);
}
protected override void SetValue(int value)
{
zNetView.GetZDO().Set(base.Key, value);
}
}
public class StringZNetProperty : ZNetProperty<string>
{
public StringZNetProperty(string key, ZNetView zNetView, string defaultValue)
: base(key, zNetView, defaultValue)
{
}
public override string Get()
{
return zNetView.GetZDO().GetString(base.Key, base.DefaultValue);
}
protected override void SetValue(string value)
{
zNetView.GetZDO().Set(base.Key, value);
}
}
public class Vector3ZNetProperty : ZNetProperty<Vector3>
{
public Vector3ZNetProperty(string key, ZNetView zNetView, Vector3 defaultValue)
: base(key, zNetView, defaultValue)
{
}//IL_0003: Unknown result type (might be due to invalid IL or missing references)
public override Vector3 Get()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
return zNetView.GetZDO().GetVec3(base.Key, base.DefaultValue);
}
protected override void SetValue(Vector3 value)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
zNetView.GetZDO().Set(base.Key, value);
}
}
public class DictionaryZNetProperty : ZNetProperty<Dictionary<SkillType, float>>
{
private BinaryFormatter binFormatter = new BinaryFormatter();
public DictionaryZNetProperty(string key, ZNetView zNetView, Dictionary<SkillType, float> defaultValue)
: base(key, zNetView, defaultValue)
{
}
public override Dictionary<SkillType, float> Get()
{
byte[] byteArray = zNetView.GetZDO().GetByteArray(base.Key, (byte[])null);
if (byteArray == null)
{
return new Dictionary<SkillType, float>();
}
MemoryStream serializationStream = new MemoryStream(byteArray);
return (Dictionary<SkillType, float>)binFormatter.Deserialize(serializationStream);
}
protected override void SetValue(Dictionary<SkillType, float> value)
{
MemoryStream memoryStream = new MemoryStream();
binFormatter.Serialize(memoryStream, value);
zNetView.GetZDO().Set(base.Key, memoryStream.ToArray());
}
public void UpdateDictionary()
{
}
}
public class ZDOIDZNetProperty : ZNetProperty<ZDOID>
{
public ZDOIDZNetProperty(string key, ZNetView zNetView, ZDOID defaultValue)
: base(key, zNetView, defaultValue)
{
}//IL_0003: Unknown result type (might be due to invalid IL or missing references)
public override ZDOID Get()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
return zNetView.GetZDO().GetZDOID(base.Key);
}
protected override void SetValue(ZDOID value)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
zNetView.GetZDO().Set(base.Key, value);
}
}
public static IDeserializer yamldeserializer = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
public static ISerializer yamlserializer = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).DisableAliases().ConfigureDefaultValuesHandling((DefaultValuesHandling)2)
.Build();
public static readonly string DeathChoiceKey = "DL_DeathChoice";
private const string color_good = "#b9f2ff";
private const string color_bad = "#ff4040";
}
internal static class DeathConfigurationData
{
[HarmonyPatch(typeof(Player))]
public static class SetupPlayerDeathlink
{
[HarmonyPostfix]
[HarmonyPatch("Load")]
private static void Postfix(Player __instance)
{
CheckAndSetPlayerDeathConfig(__instance);
}
}
public static readonly Dictionary<string, DataObjects.DeathChoiceLevel> defaultDeathLevels = new Dictionary<string, DataObjects.DeathChoiceLevel>
{
{
"Vanilla",
new DataObjects.DeathChoiceLevel
{
DisplayName = "Vanilla",
DeathStyle = new DataObjects.DeathProgressionDetails
{
itemLossStyle = DataObjects.ItemLossStyle.None,
foodLossOnDeath = true,
itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone,
minSkillLossPercentage = 0.05f,
maxSkillLossPercentage = 0.05f
},
DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(),
ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier>(),
SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier>()
}
},
{
"Rougelike1",
new DataObjects.DeathChoiceLevel
{
DisplayName = "ShieldBearer",
DeathStyle = new DataObjects.DeathProgressionDetails
{
itemLossStyle = DataObjects.ItemLossStyle.DeathlinkBased,
foodLossUsesDeathlink = true,
itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone,
minEquipmentKept = 3,
maxEquipmentKept = 9,
minItemsKept = 3,
maxItemsKept = 15,
minSkillLossPercentage = 0.03f,
maxSkillLossPercentage = 0.13f
},
DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(),
ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier> {
{
"Wood",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood" },
bonusModifer = 1.1f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
} },
SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> {
{
"All",
new DataObjects.DeathSkillModifier
{
bonusModifer = 1.05f,
skill = (SkillType)999
}
} }
}
},
{
"Rougelike2",
new DataObjects.DeathChoiceLevel
{
DisplayName = "Raider",
DeathStyle = new DataObjects.DeathProgressionDetails
{
itemLossStyle = DataObjects.ItemLossStyle.DeathlinkBased,
itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone,
minEquipmentKept = 2,
maxEquipmentKept = 6,
minSkillLossPercentage = 0.02f,
maxSkillLossPercentage = 0.14f
},
DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>(),
ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier>
{
{
"Wood",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood" },
bonusModifer = 1.2f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
},
{
"Ore",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "CopperScrap", "FlametalOreNew" },
bonusModifer = 1.2f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
}
},
SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> {
{
"All",
new DataObjects.DeathSkillModifier
{
bonusModifer = 1.1f,
skill = (SkillType)999
}
} }
}
},
{
"Rougelike3",
new DataObjects.DeathChoiceLevel
{
DisplayName = "Berserker",
DeathStyle = new DataObjects.DeathProgressionDetails
{
itemLossStyle = DataObjects.ItemLossStyle.DeathlinkBased,
itemSavedStyle = DataObjects.ItemSavedStyle.OnCharacter,
minEquipmentKept = 0,
maxEquipmentKept = 3,
minSkillLossPercentage = 0.05f,
maxSkillLossPercentage = 0.2f
},
DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier> {
{
"AmberPearl",
new DataObjects.DeathLootModifier
{
chance = 0.05f,
prefab = "AmberPearl",
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Kills }
}
} },
ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier>
{
{
"Wood",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood" },
bonusModifer = 1.5f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
},
{
"Ore",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "CopperScrap", "FlametalOreNew" },
bonusModifer = 1.5f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
}
},
SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> {
{
"All",
new DataObjects.DeathSkillModifier
{
bonusModifer = 1.2f,
skill = (SkillType)999
}
} }
}
},
{
"Hardcore",
new DataObjects.DeathChoiceLevel
{
DisplayName = "Deathbringer",
DeathStyle = new DataObjects.DeathProgressionDetails
{
itemLossStyle = DataObjects.ItemLossStyle.DestroyAll,
minSkillLossPercentage = 0.05f,
maxSkillLossPercentage = 0.25f
},
DeathLootModifiers = new Dictionary<string, DataObjects.DeathLootModifier>
{
{
"AmberPearl",
new DataObjects.DeathLootModifier
{
chance = 0.05f,
prefab = "AmberPearl",
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Kills }
}
},
{
"SmallHealthPotion",
new DataObjects.DeathLootModifier
{
chance = 0.01f,
prefab = "MeadHealthMinor",
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Kills }
}
}
},
ResourceModifiers = new Dictionary<string, DataObjects.DeathResourceModifier>
{
{
"Wood",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "Wood", "FineWood", "RoundLog", "YggdrasilWood", "Blackwood", "ElderBark" },
bonusModifer = 2f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
},
{
"Stone",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "Flint", "Stone", "BlackMarble", "Grausten" },
bonusModifer = 2f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
},
{
"Ore",
new DataObjects.DeathResourceModifier
{
prefabs = new List<string> { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "CopperScrap", "FlametalOreNew" },
bonusModifer = 2f,
bonusActions = new List<DataObjects.ResourceGainTypes> { DataObjects.ResourceGainTypes.Harvesting }
}
}
},
SkillModifiers = new Dictionary<string, DataObjects.DeathSkillModifier> {
{
"All",
new DataObjects.DeathSkillModifier
{
bonusModifer = 1.3f,
skill = (SkillType)999
}
} }
}
}
};
public static Dictionary<long, DataObjects.DeathConfiguration> playerSettings = new Dictionary<long, DataObjects.DeathConfiguration>();
public static Dictionary<string, DataObjects.DeathChoiceLevel> DeathLevels = defaultDeathLevels;
public static DataObjects.DeathChoiceLevel playerDeathConfiguration = new DataObjects.DeathChoiceLevel
{
DeathStyle = new DataObjects.DeathProgressionDetails
{
foodLossOnDeath = true,
foodLossUsesDeathlink = false,
itemLossStyle = DataObjects.ItemLossStyle.None,
minItemsKept = 0,
maxItemsKept = 0,
minEquipmentKept = 0,
maxEquipmentKept = 0,
skillLossOnDeath = true,
maxSkillLossPercentage = 0.05f,
minSkillLossPercentage = 0.05f,
itemSavedStyle = DataObjects.ItemSavedStyle.Tombstone,
nonSkillCheckedItemAction = DataObjects.NonSkillCheckedItemAction.Tombstone
}
};
internal static void Init()
{
try
{
UpdateDeathLevelsConfig(File.ReadAllText(ValConfig.deathChoicesPath));
}
catch (Exception arg)
{
Logger.LogWarning((object)$"There was an error updating the Death choice Level values, defaults will be used. Exception: {arg}");
}
try
{
UpdatePlayerConfigSettings(File.ReadAllText(ValConfig.playerSettingsPath));
}
catch (Exception arg2)
{
Logger.LogWarning((object)$"There was an error updating the player choice configs, defaults will be used. Exception: {arg2}");
}
}
public static void CheckAndSetPlayerDeathConfig(Player player)
{
if (ValConfig.UsePrivateKeysForDeathChoice.Value)
{
Logger.LogDebug("Checking private keys configurations for Deathlink");
if (player.PlayerHasUniqueKey(DataObjects.De