using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")] [assembly: AssemblyCompany("GhostMeadMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("GhostMeadMod")] [assembly: AssemblyTitle("GhostMeadMod")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GhostMeadMod { [BepInPlugin("alairaheim.ghostmead", "GhostMead", "1.8.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class GhostMeadMod : BaseUnityPlugin { public const string PluginGUID = "alairaheim.ghostmead"; public const string PluginName = "GhostMead"; public const string PluginVersion = "1.8.1"; private ConfigEntry? configGhostDuration; private ConfigEntry? configCraftingStation; private ConfigEntry? configMinStationLevel; private ConfigEntry? configMeadYield; private ConfigEntry? configIngredient1Item; private ConfigEntry? configIngredient1Amount; private ConfigEntry? configIngredient2Item; private ConfigEntry? configIngredient2Amount; private ConfigEntry? configIngredient3Item; private ConfigEntry? configIngredient3Amount; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) InitConfiguration(); RegisterLocalizations(); PrefabManager.OnPrefabsRegistered += RegisterGhostMead; new Harmony("alairaheim.ghostmead").PatchAll(); Logger.LogInfo((object)"[GhostMead] Plugin awake and Harmony patches applied successfully."); } private void InitConfiguration() { configGhostDuration = ((BaseUnityPlugin)this).Config.Bind("1 - Effect", "GhostDuration", 300f, "Duration of the Ghost Form status effect in seconds."); configCraftingStation = ((BaseUnityPlugin)this).Config.Bind("2 - Production", "CraftingStation", "piece_MeadCauldron", "Prefab name of the crafting station needed to make the mead base (e.g., piece_MeadCauldron, piece_workbench)."); configMinStationLevel = ((BaseUnityPlugin)this).Config.Bind("2 - Production", "MinStationLevel", 1, "Minimum level required for the crafting station."); configMeadYield = ((BaseUnityPlugin)this).Config.Bind("2 - Production", "FermentationYield", 5, "Number of Ghost Meads produced per fermentation batch."); configIngredient1Item = ((BaseUnityPlugin)this).Config.Bind("3 - Recipe Ingredients", "Ingredient1_Prefab", "Ectoplasm", "Prefab name for the first ingredient."); configIngredient1Amount = ((BaseUnityPlugin)this).Config.Bind("3 - Recipe Ingredients", "Ingredient1_Amount", 1, "Amount required for the first ingredient."); configIngredient2Item = ((BaseUnityPlugin)this).Config.Bind("3 - Recipe Ingredients", "Ingredient2_Prefab", "Honey", "Prefab name for the second ingredient."); configIngredient2Amount = ((BaseUnityPlugin)this).Config.Bind("3 - Recipe Ingredients", "Ingredient2_Amount", 10, "Amount required for the second ingredient."); configIngredient3Item = ((BaseUnityPlugin)this).Config.Bind("3 - Recipe Ingredients", "Ingredient3_Prefab", "BoneFragments", "Prefab name for the third ingredient."); configIngredient3Amount = ((BaseUnityPlugin)this).Config.Bind("3 - Recipe Ingredients", "Ingredient3_Amount", 5, "Amount required for the third ingredient."); } private void RegisterLocalizations() { LocalizationManager.Instance.AddToken("$item_meadbase_ghost", "Mead base: Ghost", false); LocalizationManager.Instance.AddToken("$item_meadbase_ghost_desc", "Needs to be fermented.", false); LocalizationManager.Instance.AddToken("$item_mead_ghost", "Ghost Mead", false); LocalizationManager.Instance.AddToken("$item_mead_ghost_desc", "A frothy, ethereal brew that sends a shiver down your spine.", false); LocalizationManager.Instance.AddToken("$se_ghostform_name", "Ghost Form", false); LocalizationManager.Instance.AddToken("$se_ghostform_desc", "You are undetectable to all monsters", false); } private static Sprite? LoadEmbeddedSprite(string resourceName) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) { if (stream == null) { Logger.LogWarning((object)("[GhostMead] Could not find embedded resource stream: " + resourceName)); return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); bool flag = false; Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType("UnityEngine.ImageConversion"); if (type != null) { break; } } if (type != null) { MethodInfo method = type.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }); if (method != null) { flag = (bool)(method.Invoke(null, new object[2] { val, array }) ?? ((object)false)); } } if (flag) { return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } } Logger.LogWarning((object)("[GhostMead] Failed to convert embedded resource into Texture2D: " + resourceName)); return null; } private void RegisterGhostMead() { //IL_00c4: 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_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Expected O, but got Unknown //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Expected O, but got Unknown //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Expected O, but got Unknown //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_049b: 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_04d5: Expected O, but got Unknown //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_053f: Expected O, but got Unknown //IL_053a: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Expected O, but got Unknown //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: 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_05e9: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Expected O, but got Unknown PrefabManager.OnPrefabsRegistered -= RegisterGhostMead; Color darkColor = default(Color); ((Color)(ref darkColor))..ctor(0.18f, 0.23f, 0.27f, 1f); Color darkColor2 = default(Color); ((Color)(ref darkColor2))..ctor(0.25f, 0.32f, 0.38f, 1f); Color tealColor = default(Color); ((Color)(ref tealColor))..ctor(0.1f, 0.64f, 0.57f, 1f); Sprite val = LoadEmbeddedSprite("GhostMeadMod.ghost_mead_icon.png"); Sprite val2 = LoadEmbeddedSprite("GhostMeadMod.ghost_mead_base_icon.png"); SE_GhostMead sE_GhostMead = ScriptableObject.CreateInstance(); ((Object)sE_GhostMead).name = "SE_GhostMead"; ((StatusEffect)sE_GhostMead).m_name = "$se_ghostform_name"; ((StatusEffect)sE_GhostMead).m_tooltip = "$se_ghostform_desc"; ((StatusEffect)sE_GhostMead).m_ttl = configGhostDuration?.Value ?? 300f; ((StatusEffect)sE_GhostMead).m_startMessageType = (MessageType)2; ((StatusEffect)sE_GhostMead).m_startMessage = "You fade from the perception of monsters..."; ((StatusEffect)sE_GhostMead).m_stopMessageType = (MessageType)2; ((StatusEffect)sE_GhostMead).m_stopMessage = "Monsters can see and hear you again."; GameObject prefab = PrefabManager.Instance.GetPrefab("MeadFrostResist"); if ((Object)(object)prefab != (Object)null) { ItemDrop component = prefab.GetComponent(); if (component != null) { StatusEffect consumeStatusEffect = component.m_itemData.m_shared.m_consumeStatusEffect; if (consumeStatusEffect != null) { ((StatusEffect)sE_GhostMead).m_startEffects = consumeStatusEffect.m_startEffects; ((StatusEffect)sE_GhostMead).m_stopEffects = consumeStatusEffect.m_stopEffects; if (((StatusEffect)sE_GhostMead).m_startEffects?.m_effectPrefabs != null) { EffectData[] effectPrefabs = ((StatusEffect)sE_GhostMead).m_startEffects.m_effectPrefabs; foreach (EffectData val3 in effectPrefabs) { if ((Object)(object)val3.m_prefab != (Object)null) { ApplyTealParticleTint(val3.m_prefab, tealColor); } } } } } } if ((Object)(object)val != (Object)null) { ((StatusEffect)sE_GhostMead).m_icon = val; } else { GameObject prefab2 = PrefabManager.Instance.GetPrefab("TrophyGhost"); if ((Object)(object)prefab2 != (Object)null) { ItemDrop component2 = prefab2.GetComponent(); if (component2 != null) { ((StatusEffect)sE_GhostMead).m_icon = component2.m_itemData.GetIcon(); } } } ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)sE_GhostMead, false)); CustomItem val4 = new CustomItem("MeadGhost", "MeadFrostResist"); ItemDrop itemDrop = val4.ItemDrop; itemDrop.m_itemData.m_shared.m_name = "$item_mead_ghost"; itemDrop.m_itemData.m_shared.m_description = "$item_mead_ghost_desc"; itemDrop.m_itemData.m_shared.m_consumeStatusEffect = (StatusEffect)(object)sE_GhostMead; itemDrop.m_itemData.m_shared.m_weight = 1f; GameObject prefab3 = PrefabManager.Instance.GetPrefab("Tankard_dvergr"); if ((Object)(object)prefab3 != (Object)null) { MeshFilter componentInChildren = prefab3.GetComponentInChildren(); MeshRenderer componentInChildren2 = prefab3.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null && (Object)(object)val4.ItemPrefab != (Object)null) { MeshFilter componentInChildren3 = val4.ItemPrefab.GetComponentInChildren(); MeshRenderer componentInChildren4 = val4.ItemPrefab.GetComponentInChildren(); if ((Object)(object)componentInChildren3 != (Object)null && (Object)(object)componentInChildren4 != (Object)null) { componentInChildren3.sharedMesh = componentInChildren.sharedMesh; ((Renderer)componentInChildren4).sharedMaterials = ((Renderer)componentInChildren2).sharedMaterials; } } } if ((Object)(object)val != (Object)null) { itemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val }; } ApplyDarkSilveryTint(val4.ItemPrefab, darkColor); ApplyTealParticleTint(val4.ItemPrefab, tealColor); ItemManager.Instance.AddItem(val4); CustomItem val5 = new CustomItem("MeadBaseGhost", "MeadBasePoisonResist"); ItemDrop itemDrop2 = val5.ItemDrop; itemDrop2.m_itemData.m_shared.m_name = "$item_meadbase_ghost"; itemDrop2.m_itemData.m_shared.m_description = "$item_meadbase_ghost_desc"; itemDrop2.m_itemData.m_shared.m_consumeStatusEffect = null; itemDrop2.m_itemData.m_shared.m_weight = 1f; if ((Object)(object)val2 != (Object)null) { itemDrop2.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 }; } ApplyDarkSilveryTint(val5.ItemPrefab, darkColor2); ItemManager.Instance.AddItem(val5); RequirementConfig[] requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig { Item = (configIngredient1Item?.Value ?? "Ectoplasm"), Amount = (configIngredient1Amount?.Value ?? 1) }, new RequirementConfig { Item = (configIngredient2Item?.Value ?? "Honey"), Amount = (configIngredient2Amount?.Value ?? 10) }, new RequirementConfig { Item = (configIngredient3Item?.Value ?? "BoneFragments"), Amount = (configIngredient3Amount?.Value ?? 5) } }; CustomRecipe val6 = new CustomRecipe(new RecipeConfig { Name = "Recipe_MeadBaseGhost", Item = "MeadBaseGhost", Amount = 1, CraftingStation = (configCraftingStation?.Value ?? "piece_MeadCauldron"), MinStationLevel = (configMinStationLevel?.Value ?? 1), Requirements = requirements }); ItemManager.Instance.AddRecipe(val6); GameObject val7 = PrefabManager.Instance.GetPrefab("piece_fermenter") ?? PrefabManager.Instance.GetPrefab("fermenter"); if (!((Object)(object)val7 != (Object)null)) { return; } Fermenter component3 = val7.GetComponent(); if (component3 != null) { GameObject itemPrefab = val5.ItemPrefab; ItemDrop val8 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); GameObject itemPrefab2 = val4.ItemPrefab; ItemDrop val9 = ((itemPrefab2 != null) ? itemPrefab2.GetComponent() : null); if ((Object)(object)val8 != (Object)null && (Object)(object)val9 != (Object)null) { component3.m_conversion.Add(new ItemConversion { m_from = val8, m_to = val9, m_producedItems = (configMeadYield?.Value ?? 5) }); Logger.LogInfo((object)"[GhostMead] Added Ghost Mead conversion to Fermenter."); } } } private static void ApplyDarkSilveryTint(GameObject? prefab, Color darkColor) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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) if ((Object)(object)prefab == (Object)null) { return; } Renderer[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] materials = componentsInChildren[i].materials; foreach (Material val in materials) { if (!((Object)(object)val == (Object)null)) { if (val.HasProperty("_Color")) { val.SetColor("_Color", darkColor); } if (val.HasProperty("_Tint")) { val.SetColor("_Tint", darkColor); } if (val.HasProperty("_SpecColor")) { val.SetColor("_SpecColor", new Color(0.4f, 0.45f, 0.5f, 1f)); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", Color.black); } } } } } private static void ApplyTealParticleTint(GameObject? prefab, Color tealColor) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return; } ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { MainModule main = componentsInChildren[i].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(tealColor); } ParticleSystemRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Material[] materials = ((Renderer)componentsInChildren2[i]).materials; foreach (Material val in materials) { if (!((Object)(object)val == (Object)null)) { if (val.HasProperty("_Color")) { val.SetColor("_Color", tealColor); } if (val.HasProperty("_TintColor")) { val.SetColor("_TintColor", tealColor); } } } } } } public class SE_GhostMead : StatusEffect { private GameObject? glowLightObject; public override void Setup(Character character) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) ((StatusEffect)this).Setup(character); if ((Object)(object)character != (Object)null) { glowLightObject = new GameObject("GhostMeadTealGlow"); glowLightObject.transform.SetParent(((Component)character).transform, false); glowLightObject.transform.localPosition = new Vector3(0f, 1.2f, 0f); Light obj = glowLightObject.AddComponent(); obj.type = (LightType)2; obj.color = new Color(0.2f, 0.85f, 0.77f, 1f); obj.range = 4.5f; obj.intensity = 1.8f; obj.shadows = (LightShadows)0; } } public override void Stop() { if ((Object)(object)glowLightObject != (Object)null) { Object.Destroy((Object)(object)glowLightObject); } ((StatusEffect)this).Stop(); } } [HarmonyPatch] public static class StealthPatches { private static bool IsPlayerGhosted(Character? target) { if ((Object)(object)target != (Object)null && target.IsPlayer()) { Player val = (Player)(object)((target is Player) ? target : null); if (val != null) { SEMan sEMan = ((Character)val).GetSEMan(); if (sEMan != null) { foreach (StatusEffect statusEffect in sEMan.GetStatusEffects()) { if (statusEffect is SE_GhostMead) { return true; } } } } } return false; } [HarmonyPatch(typeof(BaseAI), "CanSeeTarget", new Type[] { typeof(Character) })] [HarmonyPrefix] public static bool Prefix_CanSeeTarget(Character target, ref bool __result) { if (IsPlayerGhosted(target)) { __result = false; return false; } return true; } [HarmonyPatch(typeof(BaseAI), "CanSenseTarget", new Type[] { typeof(Character) })] [HarmonyPrefix] public static bool Prefix_CanSenseTarget(Character target, ref bool __result) { if (IsPlayerGhosted(target)) { __result = false; return false; } return true; } [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] [HarmonyPrefix] public static bool Prefix_IsEnemy(Character a, Character b, ref bool __result) { if (IsPlayerGhosted(a) || IsPlayerGhosted(b)) { __result = false; return false; } return true; } } }