Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ElPopeAdventures v1.5.0
ElPopeAdventures.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ElPopeAdventures.Blades; using ElPopeAdventures.Blades.Patches; using ElPopeAdventures.Building; using ElPopeAdventures.Building.Patches; using ElPopeAdventures.Creatures; using ElPopeAdventures.Creatures.Patches; using ElPopeAdventures.InventoryQoL; using ElPopeAdventures.InventoryQoL.Patches; using ElPopeAdventures.Mage; using ElPopeAdventures.Mage.Patches; using ElPopeAdventures.Masterwork; using ElPopeAdventures.Masterwork.Patches; using ElPopeAdventures.Rogue; using ElPopeAdventures.Rogue.Patches; using GUIFramework; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ElPopeAdventures")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.5.0.0")] [assembly: AssemblyInformationalVersion("1.5.0")] [assembly: AssemblyProduct("ElPopeAdventures")] [assembly: AssemblyTitle("ElPopeAdventures")] [assembly: AssemblyVersion("1.5.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 ElPopeAdventures { internal sealed class FollowTransform : MonoBehaviour { internal Transform Target; internal void Snap() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Target != (Object)null) { ((Component)this).transform.SetPositionAndRotation(Target.position, Target.rotation); } } private void LateUpdate() { Snap(); } } internal interface IModule { string Name { get; } string Description { get; } Type[] PatchClasses { get; } void Initialize(); void Bind(ConfigFile config); void OnSettingChanged(); void Update(); } [BepInPlugin("ElPope.ElPopeAdventures", "ElPopeAdventures", "1.5.0")] public sealed class Plugin : BaseUnityPlugin { public const string ModGuid = "ElPope.ElPopeAdventures"; public const string ModName = "ElPopeAdventures"; public const string ModVersion = "1.5.0"; internal static ManualLogSource Log; private readonly List<IModule> _active = new List<IModule>(); private Harmony _harmony; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("ElPope.ElPopeAdventures"); IModule[] array = new IModule[7] { new MageModule(), new RogueModule(), new BladesModule(), new CreaturesModule(), new MasterworkModule(), new InventoryModule(), new BuildCameraModule() }; foreach (IModule module in array) { if (!((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable" + module.Name, true, new ConfigDescription(module.Description + " Requires a game restart. In multiplayer, everyone should use the same setting.", (AcceptableValueBase)null, Array.Empty<object>())).Value) { Log.LogInfo((object)(module.Name + " module is switched off in the config.")); continue; } try { module.Bind(((BaseUnityPlugin)this).Config); module.Initialize(); } catch (Exception arg) { Log.LogError((object)$"{module.Name} module could not start and stays off: {arg}"); continue; } int num = 0; Type[] patchClasses = module.PatchClasses; foreach (Type type in patchClasses) { try { _harmony.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex) { Log.LogWarning((object)(module.Name + ": patch " + type.Name + " was not applied (" + ex.GetType().Name + ": " + ex.Message + "). The feature that needs it stays off; the rest of the game is unaffected.")); } } _active.Add(module); Log.LogInfo((object)$"{module.Name} module loaded ({num}/{module.PatchClasses.Length} patches applied)."); } ((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged; Log.LogInfo((object)"ElPopeAdventures 1.5.0 loaded."); } private void Update() { foreach (IModule item in _active) { try { item.Update(); } catch (Exception arg) { Log.LogError((object)$"{item.Name}: {arg}"); } } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void OnSettingChanged(object sender, SettingChangedEventArgs e) { foreach (IModule item in _active) { try { item.OnSettingChanged(); } catch (Exception ex) { Log.LogWarning((object)(item.Name + ": could not apply the changed settings: " + ex.Message)); } } } } internal static class TextureTools { internal static Texture2D Recolor(Texture source, Rect region, Func<Color32, Color32> recolor, bool mipmaps) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_001f: Unknown result type (might be due to invalid IL or missing references) int width; int height; Color32[] array = ReadPixels(source, region, out width, out height); for (int i = 0; i < array.Length; i++) { array[i] = recolor(array[i]); } return FromPixels(array, width, height, mipmaps); } internal static Color32[] ReadPixels(Texture source, Rect region, out int width, out int height) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) width = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref region)).width)); height = Mathf.Max(1, Mathf.RoundToInt(((Rect)(ref region)).height)); RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; Texture2D val = null; try { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(((Rect)(ref region)).width / (float)source.width, ((Rect)(ref region)).height / (float)source.height); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(((Rect)(ref region)).x / (float)source.width, ((Rect)(ref region)).y / (float)source.height); Graphics.Blit(source, temporary, val2, val3); RenderTexture.active = temporary; val = new Texture2D(width, height, (TextureFormat)4, false); val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0); return val.GetPixels32(); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } internal static Texture2D FromPixels(Color32[] pixels, int width, int height, bool mipmaps) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown Texture2D val = new Texture2D(width, height, (TextureFormat)4, mipmaps); val.SetPixels32(pixels); val.Apply(mipmaps, true); ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20); return val; } internal static float Step(float a, float b, float x) { return Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(a, b, x)); } } } namespace ElPopeAdventures.Rogue { internal static class RogueClass { private const string ClassKey = "ElPope.Rogue"; private const string ClassValue = "Rogue"; private static float s_nextRefusal; private static float s_nextEffectCheck; internal static bool IsRogue(Player player) { if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue("ElPope.Rogue", out var value)) { return value == "Rogue"; } return false; } internal static bool DaggersLocked(Player player) { if (Settings.DaggersRequireRogue && (Object)(object)player != (Object)null) { return !IsRogue(player); } return false; } internal static bool RefuseDagger(Player player) { if ((Object)(object)player != (Object)(object)Player.m_localPlayer || !DaggersLocked(player) || !RogueItems.IsDagger(((Humanoid)player).GetCurrentWeapon())) { return false; } Refuse(player, "Only a Rogue can fight with these. Use a Rogue's Shadowstone first."); return true; } internal static void Refuse(Player player, string message) { if (Time.time >= s_nextRefusal) { s_nextRefusal = Time.time + 2f; ((Character)player).Message((MessageType)2, message, 0, (Sprite)null, false); } } internal static bool RefuseTome(Player player, ItemData item) { if (!RogueItems.IsTome(item) || !IsRogue(player)) { return false; } ((Character)player).Message((MessageType)2, "You are already a Rogue.", 0, (Sprite)null, false); return true; } internal static void OnConsumed(Player player, ItemData item) { if (RogueItems.IsTome(item) && !IsRogue(player)) { player.m_customData["ElPope.Rogue"] = "Rogue"; KeepEffect(player, force: true); ((Character)player).Message((MessageType)2, "You have become a Rogue!", 0, (Sprite)null, false); RogueModule.Log.LogInfo((object)(player.GetPlayerName() + " became a Rogue.")); } } internal static void KeepEffect(Player player, bool force = false) { if (!force && Time.time < s_nextEffectCheck) { return; } s_nextEffectCheck = Time.time + 1f; SE_Stats rogueEffect = RogueItems.RogueEffect; if (!((Object)(object)player == (Object)null) && !((Object)(object)rogueEffect == (Object)null) && !((Character)player).IsDead() && IsRogue(player)) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null && !sEMan.HaveStatusEffect(((StatusEffect)rogueEffect).NameHash())) { sEMan.AddStatusEffect((StatusEffect)(object)rogueEffect, false, 0, 0f, (short)(-1)); } } } } internal sealed class DaggerDef { internal string Id; internal string Name; internal string Description; internal int Tier; internal string Station; internal int StationLevel = 1; internal string DefaultRecipe; internal float Damage; internal float Spirit; internal float Stamina; internal DaggerPalette Palette; internal string ConfigKey => Id.Substring("ElPopeRogue_".Length); } internal static class RogueContent { internal const string IdPrefix = "ElPopeRogue_"; internal const string TomeId = "ElPopeRogue_Shadowstone"; internal const string TomeName = "Rogue's Shadowstone"; internal const string TomeDescription = "A stone that swallows the light around it. Hold it close to learn the ways of shadow and become a Rogue: you move quieter and harder to spot, sneaking tires you less, your daggers strike harder, and you can craft and wield dual daggers."; internal const string TomeRecipe = "LeatherScraps:4,Flint:6,Mushroom:3"; internal static readonly string[] TomeSources = new string[2] { "Thunderstone", "Flint" }; internal const string DaggerSource = "KnifeSkollAndHati"; internal const float SourceDamage = 45f; internal const float SourceStamina = 42f; internal static readonly string[] Biomes = new string[5] { "Meadows", "Black Forest", "Swamp", "Mountain", "Plains" }; private const string Workbench = "$piece_workbench"; private const string Forge = "$piece_forge"; internal static readonly DaggerDef[] Daggers = new DaggerDef[5] { new DaggerDef { Id = "ElPopeRogue_FlintFangs", Name = "Flint Fangs", Tier = 0, Station = "$piece_workbench", StationLevel = 2, DefaultRecipe = "Wood:4,Flint:10,LeatherScraps:4", Damage = 7f, Stamina = 12f, Description = "A pair of knapped flint blades bound in leather. Quick, quiet and cruel.", Palette = new DaggerPalette(28f, 0.55f, 1.6f, 30f, 0.08f, 0.7f) }, new DaggerDef { Id = "ElPopeRogue_BronzeFangs", Name = "Bronze Fangs", Tier = 1, Station = "$piece_forge", StationLevel = 1, DefaultRecipe = "Wood:4,Bronze:8,DeerHide:4", Damage = 14f, Stamina = 18f, Description = "Twin bronze daggers, balanced for throwing your weight behind every cut.", Palette = new DaggerPalette(20f, 0.5f, 1.3f, 32f, 0.6f, 0.85f) }, new DaggerDef { Id = "ElPopeRogue_IronFangs", Name = "Iron Fangs", Tier = 2, Station = "$piece_forge", StationLevel = 2, DefaultRecipe = "ElderBark:4,Iron:10,LeatherScraps:6", Damage = 20f, Stamina = 24f, Description = "Iron daggers wrapped in blood-dark leather. They find the gaps in any armour.", Palette = new DaggerPalette(355f, 0.55f, 1.4f, 210f, 0.08f, 0.75f) }, new DaggerDef { Id = "ElPopeRogue_SilverFangs", Name = "Silver Fangs", Tier = 3, Station = "$piece_forge", StationLevel = 3, DefaultRecipe = "ElderBark:4,Silver:12,WolfPelt:2", Damage = 26f, Spirit = 10f, Stamina = 30f, Description = "Silver bites the undead. Wolf-pelt grips keep your hands warm on the mountain.", Palette = new DaggerPalette(205f, 0.35f, 2f, 200f, 0.06f, 1f) }, new DaggerDef { Id = "ElPopeRogue_BlackmetalFangs", Name = "Blackmetal Fangs", Tier = 4, Station = "$piece_forge", StationLevel = 4, DefaultRecipe = "FineWood:4,BlackMetal:12,LinenThread:6", Damage = 34f, Stamina = 36f, Description = "Fuling black metal with gilded grips. The last word before Skoll and Hati.", Palette = new DaggerPalette(44f, 0.6f, 2.6f, 160f, 0.25f, 0.35f) } }; } internal readonly struct DaggerPalette { private readonly float _handleHue; private readonly float _handleSaturation; private readonly float _handleValue; private readonly float _bladeHue; private readonly float _bladeSaturation; private readonly float _bladeValue; internal DaggerPalette(float handleHue, float handleSaturation, float handleValue, float bladeHue, float bladeSaturation, float bladeValue) { _handleHue = handleHue / 360f; _handleSaturation = handleSaturation; _handleValue = handleValue; _bladeHue = bladeHue / 360f; _bladeSaturation = bladeSaturation; _bladeValue = bladeValue; } internal Color32 Apply(Color32 pixel) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_00f9: 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) float num = default(float); float x = default(float); float num2 = default(float); Color.RGBToHSV(Color32.op_Implicit(pixel), ref num, ref x, ref num2); float num3 = num * 360f; float num4 = (1f - TextureTools.Step(35f, 55f, Mathf.Abs(num3 - 128f))) * TextureTools.Step(0.1f, 0.2f, x); float num5 = (1f - TextureTools.Step(15f, 30f, Mathf.Abs(num3 - 25f))) * TextureTools.Step(0.25f, 0.4f, x); Color val; float num6; if (num4 > 0f) { val = Color.HSVToRGB(_handleHue, _handleSaturation, Mathf.Clamp01(num2 * _handleValue)); num6 = num4; } else { if (!(num5 > 0f)) { return pixel; } val = Color.HSVToRGB(_bladeHue, _bladeSaturation, Mathf.Clamp01(num2 * _bladeValue)); num6 = num5; } Color32 result = Color32.op_Implicit(Color.Lerp(Color32.op_Implicit(pixel), val, num6)); result.a = pixel.a; return result; } } internal static class RogueItems { private const string RecipePrefix = "Recipe_ElPopeRogue_"; private static readonly MethodInfo s_updateRegisters = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); private static readonly FieldInfo s_namedPrefabs = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); private static readonly HashSet<string> s_warned = new HashSet<string>(); private static readonly Dictionary<string, ItemDrop> s_items = new Dictionary<string, ItemDrop>(); private static readonly Dictionary<string, DaggerDef> s_daggerDefs = RogueContent.Daggers.ToDictionary((DaggerDef d) => d.Id); private static readonly Dictionary<(int, int), Material> s_materials = new Dictionary<(int, int), Material>(); private static readonly Dictionary<(int, int), Sprite> s_icons = new Dictionary<(int, int), Sprite>(); private static GameObject s_container; internal static SE_Stats RogueEffect { get; private set; } internal static bool IsTome(ItemData item) { return Is(item, "ElPopeRogue_Shadowstone"); } internal static DaggerDef DaggerDef(ItemData item) { if (item == null) { return null; } DaggerDef[] daggers = RogueContent.Daggers; foreach (DaggerDef daggerDef in daggers) { if (Is(item, daggerDef.Id)) { return daggerDef; } } return null; } internal static bool IsDagger(ItemData item) { return DaggerDef(item) != null; } private static bool Is(ItemData item, string id) { if (item != null && s_items.TryGetValue(id, out var value) && (Object)(object)value != (Object)null) { if (item.m_shared != value.m_itemData.m_shared) { if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name == id; } return false; } return true; } return false; } internal static bool IsRogueOnlyRecipe(Recipe recipe) { if ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null) { return s_daggerDefs.ContainsKey(((Object)recipe.m_item).name ?? ""); } return false; } internal static void RegisterInObjectDB(ObjectDB db) { if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0) { return; } EnsureBuilt((Func<string, GameObject>)db.GetItemPrefab); bool flag = false; foreach (ItemDrop item in s_items.Values.Where((ItemDrop i) => (Object)(object)i != (Object)null)) { if (!db.m_items.Contains(((Component)item).gameObject)) { db.m_items.Add(((Component)item).gameObject); flag = true; } } if ((Object)(object)RogueEffect != (Object)null && !db.m_StatusEffects.Contains((StatusEffect)(object)RogueEffect)) { db.m_StatusEffects.Add((StatusEffect)(object)RogueEffect); } if (flag) { s_updateRegisters.Invoke(db, null); } ApplySettings(); RebuildRecipes(db); } internal static void RegisterInScene(ZNetScene scene) { EnsureBuilt((Func<string, GameObject>)scene.GetPrefab); if (!(s_namedPrefabs?.GetValue(scene) is Dictionary<int, GameObject> dictionary)) { Warn("scene", "Could not add the rogue items to the game's network prefab list; they cannot be dropped on the ground."); return; } foreach (ItemDrop item in s_items.Values.Where((ItemDrop i) => (Object)(object)i != (Object)null)) { if (!scene.m_prefabs.Contains(((Component)item).gameObject)) { scene.m_prefabs.Add(((Component)item).gameObject); } dictionary[StringExtensionMethods.GetStableHashCode(((Object)item).name)] = ((Component)item).gameObject; } } private static void EnsureBuilt(Func<string, GameObject> find) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)s_container == (Object)null) { s_container = new GameObject("ElPopeRogue_Prefabs"); s_container.SetActive(false); Object.DontDestroyOnLoad((Object)(object)s_container); } if ((Object)(object)RogueEffect == (Object)null) { RogueEffect = CreateRogueEffect(); } if (!s_items.ContainsKey("ElPopeRogue_Shadowstone")) { ItemDrop val = BuildTome(find); if ((Object)(object)val != (Object)null) { s_items["ElPopeRogue_Shadowstone"] = val; } } DaggerDef[] daggers = RogueContent.Daggers; foreach (DaggerDef daggerDef in daggers) { if (!s_items.ContainsKey(daggerDef.Id)) { ItemDrop val2 = BuildDagger(daggerDef, find); if ((Object)(object)val2 != (Object)null) { s_items[daggerDef.Id] = val2; } } } } private static SE_Stats CreateRogueEffect() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) SE_Stats obj = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)obj).name = "ElPopeRogue_Class"; ((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x20); ((StatusEffect)obj).m_name = "Rogue"; obj.m_modifyAttackSkill = (SkillType)2; return obj; } private static ItemDrop BuildTome(Func<string, GameObject> find) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) ItemDrop val = CloneItem(find, RogueContent.TomeSources, "ElPopeRogue_Shadowstone", "Rogue's Shadowstone", "A stone that swallows the light around it. Hold it close to learn the ways of shadow and become a Rogue: you move quieter and harder to spot, sneaking tires you less, your daggers strike harder, and you can craft and wield dual daggers."); if ((Object)(object)val == (Object)null) { return null; } SharedData shared = val.m_itemData.m_shared; shared.m_itemType = (ItemType)2; shared.m_food = 0f; shared.m_foodStamina = 0f; shared.m_foodEitr = 0f; shared.m_consumeStatusEffect = null; shared.m_questItem = false; shared.m_teleportable = true; shared.m_maxStackSize = 1; shared.m_maxQuality = 1; if ((Object)(object)RogueEffect != (Object)null && shared.m_icons != null && shared.m_icons.Length != 0) { ((StatusEffect)RogueEffect).m_icon = shared.m_icons[0]; } return val; } private static ItemDrop BuildDagger(DaggerDef def, Func<string, GameObject> find) { ItemDrop val = CloneItem(find, new string[1] { "KnifeSkollAndHati" }, def.Id, def.Name, def.Description); if ((Object)(object)val == (Object)null) { return null; } SharedData shared = val.m_itemData.m_shared; float num = def.Damage / 45f; ((DamageTypes)(ref shared.m_damages)).Modify(num); shared.m_damages.m_spirit += def.Spirit; ((DamageTypes)(ref shared.m_damagesPerLevel)).Modify(num); float num2 = def.Stamina / 42f; if (shared.m_attack != null) { Attack attack = shared.m_attack; attack.m_attackStamina *= num2; } if (!Shadowstep.MakeSecondary(shared, def.Stamina)) { Warn(def.Id + " special", def.Name + " keeps the vanilla Skoll and Hati secondary attack."); } shared.m_description += "\n\nSecondary attack: Shadowstep. Vanish, reappear behind the enemy you are facing and strike it from behind."; try { Recolor(val, def); } catch (Exception ex) { Warn(def.Id + " look", "Could not recolour " + def.Name + ", so it looks like Skoll and Hati (" + ex.Message + ")."); } return val; } private static void Recolor(ItemDrop item, DaggerDef def) { Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!(val is ParticleSystemRenderer)) { Material[] sharedMaterials = val.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { sharedMaterials[j] = Recolored(sharedMaterials[j], def); } val.sharedMaterials = sharedMaterials; } } SharedData shared = item.m_itemData.m_shared; if (shared.m_icons != null && shared.m_icons.Length != 0) { shared.m_icons = shared.m_icons.Select((Sprite icon) => RecoloredIcon(icon, def)).ToArray(); } } private static Material Recolored(Material source, DaggerDef def) { //IL_005a: 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_007c: Expected O, but got Unknown //IL_007e: 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) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && source.HasProperty("_MainTex")) { Texture texture = source.GetTexture("_MainTex"); Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (val != null) { (int, int) key = (((Object)source).GetInstanceID(), def.Tier); if (s_materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Material val2 = new Material(source) { name = ((Object)source).name + "_" + def.ConfigKey }; ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20); Texture2D val3 = TextureTools.Recolor((Texture)(object)val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), def.Palette.Apply, ((Texture)val).mipmapCount > 1); ((Object)val3).name = ((Object)val).name + "_" + def.ConfigKey; ((Texture)val3).wrapMode = ((Texture)val).wrapMode; ((Texture)val3).filterMode = ((Texture)val).filterMode; val2.SetTexture("_MainTex", (Texture)(object)val3); s_materials[key] = val2; return val2; } } return source; } private static Sprite RecoloredIcon(Sprite source, DaggerDef def) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } (int, int) key = (((Object)source).GetInstanceID(), def.Tier); if (s_icons.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Rect textureRect; try { textureRect = source.textureRect; } catch (Exception) { return source; } Texture2D val = TextureTools.Recolor((Texture)(object)source.texture, textureRect, def.Palette.Apply, mipmaps: false); ((Object)val).name = ((Object)source).name + "_" + def.ConfigKey; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit); ((Object)val2).name = ((Object)val).name; ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20); s_icons[key] = val2; return val2; } private static ItemDrop CloneItem(Func<string, GameObject> find, string[] sources, string id, string name, string description) { foreach (string text in sources) { GameObject val = find(text); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (val2?.m_itemData?.m_shared != null) { GameObject val3 = Object.Instantiate<GameObject>(val, s_container.transform, false); ((Object)val3).name = id; ItemDrop component = val3.GetComponent<ItemDrop>(); SharedData shared = component.m_itemData.m_shared; SharedData shared2 = val2.m_itemData.m_shared; if (shared == shared2 || (shared.m_attack != null && shared.m_attack == shared2.m_attack) || (shared.m_secondaryAttack != null && shared.m_secondaryAttack == shared2.m_secondaryAttack)) { Object.DestroyImmediate((Object)(object)val3); Warn(id, "Could not make an independent copy of '" + text + "', so " + name + " is unavailable."); return null; } component.m_itemData.m_dropPrefab = val3; shared.m_name = name; shared.m_description = description; return component; } } Warn(id, "None of the vanilla items " + string.Join(", ", sources) + " exist in this game version, so " + name + " is unavailable."); return null; } internal static void ApplySettings() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RogueEffect != (Object)null) { RogueEffect.m_damageModifier = 1f + Settings.DaggerDamageBonus; RogueEffect.m_sneakStaminaUseModifier = 0f - Settings.SneakStaminaReduction; RogueEffect.m_noiseModifier = 0f - Settings.StealthBonus; RogueEffect.m_stealthModifier = 0f - Settings.StealthBonus; ((StatusEffect)RogueEffect).m_tooltip = $"Knives and daggers: +{Settings.DaggerDamageBonus * 100f:0}% damage, " + $"+{Settings.SneakAttackBonus * 100f:0}% sneak attack damage"; } DaggerDef[] daggers = RogueContent.Daggers; foreach (DaggerDef daggerDef in daggers) { if (s_items.TryGetValue(daggerDef.Id, out var value) && (Object)(object)value != (Object)null) { DamageTypes damages = value.m_itemData.m_shared.m_damages; RogueModule.Log.LogInfo((object)($"{daggerDef.Name} ({RogueContent.Biomes[daggerDef.Tier]}): {damages.m_slash:0.#} slash + {damages.m_pierce:0.#} pierce" + ((damages.m_spirit > 0f) ? $" + {damages.m_spirit:0.#} spirit" : "") + $". Shadowstep: {Settings.ShadowstepDamage:0.#}x damage, {Shadowstep.StaminaOf(value.m_itemData):0} stamina, " + $"{Settings.ShadowstepRange:0} m.")); } } } private static void RebuildRecipes(ObjectDB db) { Recipe[] array = db.m_recipes.Where((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name.StartsWith("Recipe_ElPopeRogue_")).ToArray(); foreach (Recipe val in array) { db.m_recipes.Remove(val); Object.Destroy((Object)(object)val); } Dictionary<string, CraftingStation> dictionary = new Dictionary<string, CraftingStation>(); foreach (Recipe recipe in db.m_recipes) { CraftingStation val2 = (((Object)(object)recipe != (Object)null) ? recipe.m_craftingStation : null); if ((Object)(object)val2 != (Object)null && !dictionary.ContainsKey(val2.m_name)) { dictionary[val2.m_name] = val2; } } if (s_items.TryGetValue("ElPopeRogue_Shadowstone", out var value) && (Object)(object)value != (Object)null) { AddRecipe(db, dictionary, value, "Rogue's Shadowstone", "$piece_workbench", 1, RecipeSpec("Shadowstone", "LeatherScraps:4,Flint:6,Mushroom:3"), -1); } DaggerDef[] daggers = RogueContent.Daggers; foreach (DaggerDef daggerDef in daggers) { if (s_items.TryGetValue(daggerDef.Id, out var value2) && (Object)(object)value2 != (Object)null) { AddRecipe(db, dictionary, value2, daggerDef.Name, daggerDef.Station, daggerDef.StationLevel, RecipeSpec(daggerDef.ConfigKey, daggerDef.DefaultRecipe), daggerDef.Tier); } } } private static string RecipeSpec(string key, string fallback) { if (!Settings.Recipes.TryGetValue(key, out var value)) { return fallback; } return value; } private static void AddRecipe(ObjectDB db, Dictionary<string, CraftingStation> stations, ItemDrop item, string name, string station, int stationLevel, string spec, int upgradeTier) { //IL_0072: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown List<Requirement> list = new List<Requirement>(ParseRequirements(db, spec, name)); if (list.Count == 0) { Warn("recipe " + ((Object)item).name, "The recipe for " + name + " has no valid ingredients, so it cannot be crafted."); return; } if (upgradeTier >= 0) { GameObject itemPrefab = db.GetItemPrefab($"Upgrader{upgradeTier}Weapon"); if ((Object)(object)itemPrefab != (Object)null && (Object)(object)itemPrefab.GetComponent<ItemDrop>() != (Object)null) { list.Add(new Requirement { m_resItem = itemPrefab.GetComponent<ItemDrop>(), m_amount = 1, m_amountPerLevel = 0, m_upgraderResource = true, m_recover = false }); } } stations.TryGetValue(station ?? "", out var value); if ((Object)(object)value == (Object)null && !string.IsNullOrEmpty(station)) { Warn("station " + station, "Crafting station " + station + " was not found; items that need it can be crafted without one."); } Recipe val = ScriptableObject.CreateInstance<Recipe>(); ((Object)val).name = "Recipe_" + ((Object)item).name; val.m_item = item; val.m_amount = 1; val.m_enabled = true; val.m_craftingStation = value; val.m_minStationLevel = stationLevel; val.m_resources = list.ToArray(); db.m_recipes.Add(val); } private static IEnumerable<Requirement> ParseRequirements(ObjectDB db, string spec, string forItem) { string[] array = (spec ?? "").Split(new char[1] { ',' }); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }); string text2 = array2[0].Trim(); if (text2.Length == 0) { continue; } int result = 1; int result2 = -1; if ((array2.Length > 1 && (!int.TryParse(array2[1].Trim(), out result) || result < 1)) || (array2.Length > 2 && (!int.TryParse(array2[2].Trim(), out result2) || result2 < 0))) { Warn(forItem + text, "Ingredient '" + text.Trim() + "' for " + forItem + " has an invalid amount; it is ignored."); continue; } GameObject itemPrefab = db.GetItemPrefab(text2); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { Warn(forItem + text2, "Ingredient '" + text2 + "' for " + forItem + " is not an item this game knows; it is ignored."); continue; } if (result2 < 0) { result2 = ((!text2.StartsWith("Trophy")) ? Mathf.Max(1, (result + 1) / 2) : 0); } yield return new Requirement { m_resItem = val, m_amount = result, m_amountPerLevel = result2, m_recover = true }; } } internal static void Warn(string key, string message) { if (s_warned.Add(key)) { RogueModule.Log.LogWarning((object)message); } } } internal sealed class RogueModule : IModule { internal static readonly ManualLogSource Log = Logger.CreateLogSource("ElPopeAdventures.Rogue"); private ConfigEntry<bool> _daggersRequireRogue; private ConfigEntry<float> _daggerDamage; private ConfigEntry<float> _sneakAttack; private ConfigEntry<float> _sneakStamina; private ConfigEntry<float> _stealth; private ConfigEntry<float> _stepRange; private ConfigEntry<float> _stepDamage; private readonly Dictionary<string, ConfigEntry<string>> _recipes = new Dictionary<string, ConfigEntry<string>>(); public string Name => "Rogue"; public string Description => "The Rogue class: stealth and dagger bonuses, and dual daggers with Shadowstep for every biome up to the Plains."; public Type[] PatchClasses { get; } = new Type[9] { typeof(ElPopeAdventures.Rogue.Patches.ObjectDBAwake), typeof(ElPopeAdventures.Rogue.Patches.ObjectDBCopyOtherDB), typeof(ElPopeAdventures.Rogue.Patches.ZNetSceneAwake), typeof(ElPopeAdventures.Rogue.Patches.PlayerConsumeItem), typeof(ElPopeAdventures.Rogue.Patches.PlayerHaveRequirementsRecipe), typeof(ElPopeAdventures.Rogue.Patches.PlayerGetAvailableRecipes), typeof(ElPopeAdventures.Rogue.Patches.HumanoidStartAttack), typeof(ElPopeAdventures.Rogue.Patches.AttackOnAttackTrigger), typeof(ElPopeAdventures.Rogue.Patches.CharacterDamage) }; public void Initialize() { } public void Bind(ConfigFile config) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown _daggersRequireRogue = config.Bind<bool>("Rogue - Class", "DaggersRequireRogue", true, "If true, dual dagger recipes only appear after the character uses a Rogue's Shadowstone, and only a Rogue can fight with them. Vanilla knives are never affected."); _daggerDamage = config.Bind<float>("Rogue - Class", "KnifeDamageBonus", 0.1f, new ConfigDescription("Extra damage a Rogue deals with every knife and dagger (0.1 = +10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _sneakAttack = config.Bind<float>("Rogue - Class", "SneakAttackBonus", 0.5f, new ConfigDescription("Extra damage on a Rogue's sneak attacks with knives, on top of the knife's own sneak attack bonus (0.5 = +50%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); _sneakStamina = config.Bind<float>("Rogue - Class", "SneakStaminaReduction", 0.5f, new ConfigDescription("How much less stamina sneaking costs a Rogue (0.5 = half).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.9f), Array.Empty<object>())); _stealth = config.Bind<float>("Rogue - Class", "StealthBonus", 0.25f, new ConfigDescription("How much quieter and harder to spot a Rogue is (0.25 = 25%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.9f), Array.Empty<object>())); _stepRange = config.Bind<float>("Rogue - Shadowstep", "Range", 10f, new ConfigDescription("How far (in metres) Shadowstep reaches. It picks the enemy closest to where you are looking.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 25f), Array.Empty<object>())); _stepDamage = config.Bind<float>("Rogue - Shadowstep", "DamageMultiplier", 2.5f, new ConfigDescription("Shadowstep's strike deals this many times the daggers' normal damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>())); _recipes["Shadowstone"] = config.Bind<string>("Rogue - Recipes", "Shadowstone", "LeatherScraps:4,Flint:6,Mushroom:3", "Rogue's Shadowstone. Ingredients as ItemName:Amount pairs. Applies on the next world load."); DaggerDef[] daggers = RogueContent.Daggers; foreach (DaggerDef daggerDef in daggers) { _recipes[daggerDef.ConfigKey] = config.Bind<string>("Rogue - Recipes", daggerDef.ConfigKey, daggerDef.DefaultRecipe, daggerDef.Name + ", dual daggers, " + RogueContent.Biomes[daggerDef.Tier] + ". Ingredients as ItemName:Amount pairs (optionally ItemName:Amount:PerUpgradeLevel). Applies on the next world load."); } PullSettings(); } public void OnSettingChanged() { PullSettings(); RogueItems.ApplySettings(); } public void Update() { RogueClass.KeepEffect(Player.m_localPlayer); } private void PullSettings() { Settings.DaggersRequireRogue = _daggersRequireRogue.Value; Settings.DaggerDamageBonus = _daggerDamage.Value; Settings.SneakAttackBonus = _sneakAttack.Value; Settings.SneakStaminaReduction = _sneakStamina.Value; Settings.StealthBonus = _stealth.Value; Settings.ShadowstepRange = _stepRange.Value; Settings.ShadowstepDamage = _stepDamage.Value; foreach (KeyValuePair<string, ConfigEntry<string>> recipe in _recipes) { Settings.Recipes[recipe.Key] = recipe.Value.Value ?? ""; } } } internal static class Settings { internal static bool DaggersRequireRogue = true; internal static float DaggerDamageBonus = 0.1f; internal static float SneakAttackBonus = 0.5f; internal static float SneakStaminaReduction = 0.5f; internal static float StealthBonus = 0.25f; internal static float ShadowstepRange = 10f; internal static float ShadowstepDamage = 2.5f; internal static readonly Dictionary<string, string> Recipes = new Dictionary<string, string>(); } internal static class Shadowstep { private const float AimAngle = 50f; private const float StrikeReach = 3f; private const float StrikeTimeout = 3f; private const float MaxHeightDifference = 2.5f; private const string SmokeEffect = "vfx_odin_despawn"; private const string StrikeEffect = "fx_backstab"; private static readonly FieldInfo s_attackCharacter = AccessTools.Field(typeof(Attack), "m_character"); private static readonly FieldInfo s_attackWeapon = AccessTools.Field(typeof(Attack), "m_weapon"); private static readonly List<Character> s_nearby = new List<Character>(); private static readonly Dictionary<string, GameObject> s_effects = new Dictionary<string, GameObject>(); private static int s_sightMask; private static int s_solidMask; private static int s_groundMask; private static Character s_pendingTarget; private static Vector3 s_pendingDestination; private static Character s_target; private static float s_targetUntil; internal static bool MakeSecondary(SharedData shared, float stamina) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) Attack secondaryAttack = shared.m_secondaryAttack; if (secondaryAttack == null || string.IsNullOrEmpty(secondaryAttack.m_attackAnimation)) { return false; } Attack val = secondaryAttack.Clone(); val.m_attackType = (AttackType)3; val.m_attackStamina = stamina; val.m_attackProjectile = null; val.m_spawnOnTrigger = null; shared.m_secondaryAttack = val; return true; } internal static float StaminaOf(ItemData item) { return item.m_shared.m_secondaryAttack?.m_attackStamina ?? 0f; } private static bool IsShadowstep(Attack attack, ItemData weapon) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if (weapon != null && attack != null && (int)attack.m_attackType == 3 && RogueItems.IsDagger(weapon)) { return attack.m_attackAnimation == weapon.m_shared.m_secondaryAttack?.m_attackAnimation; } return false; } internal static bool BeforeStartAttack(Humanoid humanoid, bool secondaryAttack) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) s_pendingTarget = null; if (secondaryAttack) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && RogueItems.IsDagger(((Humanoid)val).GetCurrentWeapon()) && !((Character)val).InAttack()) { EnsureMasks(); Vector3 destination; Character val2 = FindTarget(val, out destination); if ((Object)(object)val2 == (Object)null) { RogueClass.Refuse(val, "No enemy in reach to Shadowstep behind."); return true; } s_pendingTarget = val2; s_pendingDestination = destination; return false; } } return false; } internal static void AfterStartAttack(Humanoid humanoid, bool started) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00c4: Unknown result type (might be due to invalid IL or missing references) Character val = s_pendingTarget; s_pendingTarget = null; if (!started || (Object)(object)val == (Object)null) { return; } Player val2 = (Player)(object)((humanoid is Player) ? humanoid : null); if (val2 != null && !((Object)(object)val2 != (Object)(object)Player.m_localPlayer)) { SpawnEffect("vfx_odin_despawn", ((Component)val2).transform.position, Quaternion.identity); Vector3 val3 = s_pendingDestination; Vector3 val4 = ((Component)val).transform.position - val3; val4.y = 0f; Quaternion val5 = ((((Vector3)(ref val4)).sqrMagnitude > 0.001f) ? Quaternion.LookRotation(val4) : ((Component)val2).transform.rotation); Rigidbody component = ((Component)val2).GetComponent<Rigidbody>(); ((Component)val2).transform.SetPositionAndRotation(val3, val5); if ((Object)(object)component != (Object)null) { component.position = val3; component.rotation = val5; component.linearVelocity = Vector3.zero; } ((Character)val2).SetLookDir(val5 * Vector3.forward, 0f); val2.SetMouseLookForward(false); SpawnEffect("vfx_odin_despawn", val3, Quaternion.identity); s_target = val; s_targetUntil = Time.time + 3f; } } internal static void OnTrigger(Attack attack) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_target == (Object)null) { return; } object? obj = s_attackCharacter?.GetValue(attack); Character val = (Character)((obj is Character) ? obj : null); object? obj2 = s_attackWeapon?.GetValue(attack); ItemData val2 = (ItemData)((obj2 is ItemData) ? obj2 : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && IsShadowstep(attack, val2)) { Character val3 = s_target; s_target = null; if (!((Object)(object)val3 == (Object)null) && !val3.IsDead() && !(Time.time > s_targetUntil) && !(Vector3.Distance(((Component)val).transform.position, ((Component)val3).transform.position) > val3.GetRadius() + 3f)) { Vector3 val4 = ((Component)val3).transform.position - ((Component)val).transform.position; val4.y = 0f; HitData val5 = new HitData { m_damage = val2.GetDamage(), m_point = val3.GetCenterPoint(), m_dir = ((((Vector3)(ref val4)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val4)).normalized : ((Component)val).transform.forward), m_pushForce = val2.m_shared.m_attackForce, m_backstabBonus = 1f, m_staggerMultiplier = 1f, m_dodgeable = true, m_blockable = false, m_skill = (SkillType)2, m_skillRaiseAmount = 1f, m_toolTier = (short)val2.m_shared.m_toolTier, m_hitType = (HitType)2 }; ((DamageTypes)(ref val5.m_damage)).Modify(Settings.ShadowstepDamage * val.GetRandomSkillFactor((SkillType)2)); val5.SetAttacker(val); val.GetSEMan().ModifyAttack((SkillType)2, ref val5); val3.Damage(val5); SpawnEffect("fx_backstab", val5.m_point, Quaternion.identity); val.RaiseSkill((SkillType)2, 1f); } } } private static Character FindTarget(Player player, out Vector3 destination) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) destination = Vector3.zero; Vector3 position = ((Character)player).m_eye.position; Vector3 val = (((Object)(object)GameCamera.instance != (Object)null) ? ((Component)GameCamera.instance).transform.forward : ((Component)player).transform.forward); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = ((Component)player).transform.forward; } s_nearby.Clear(); Character.GetCharactersInRange(((Component)player).transform.position, Settings.ShadowstepRange, s_nearby); Character result = null; float num = float.MaxValue; foreach (Character item in s_nearby) { if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)player || item.IsDead() || !BaseAI.IsEnemy((Character)(object)player, item)) { continue; } Vector3 centerPoint = item.GetCenterPoint(); Vector3 val2 = centerPoint - position; val2.y = 0f; float num2 = Vector3.Angle(val, val2); if (!(num2 > 50f) && !Physics.Linecast(position, centerPoint, s_sightMask)) { float num3 = num2 + ((Vector3)(ref val2)).magnitude * 2f; if (num3 < num && TryFindSpotBehind(item, out var spot)) { result = item; num = num3; destination = spot; } } } return result; } private static bool TryFindSpotBehind(Character target, out Vector3 spot) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)target).transform.position; Vector3 val = -((Component)target).transform.forward; val.y = 0f; val = ((((Vector3)(ref val)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val)).normalized : Vector3.back); float num = target.GetRadius() + 0.9f; Vector3 centerPoint = target.GetCenterPoint(); float[] array = new float[5] { 0f, 40f, -40f, 80f, -80f }; RaycastHit val2 = default(RaycastHit); foreach (float num2 in array) { spot = position + Quaternion.Euler(0f, num2, 0f) * val * num; if (Physics.Raycast(spot + Vector3.up * 3f, Vector3.down, ref val2, 6f, s_groundMask)) { spot.y = ((RaycastHit)(ref val2)).point.y; if (!(Mathf.Abs(spot.y - position.y) > 2.5f) && !Physics.CheckCapsule(spot + Vector3.up * 0.6f, spot + Vector3.up * 1.5f, 0.4f, s_solidMask) && !Physics.Linecast(centerPoint, spot + Vector3.up * 1f, s_sightMask)) { return true; } } } spot = Vector3.zero; return false; } private static void EnsureMasks() { if (s_solidMask == 0) { s_sightMask = LayerMask.GetMask(new string[4] { "Default", "static_solid", "terrain", "piece" }); s_solidMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "vehicle" }); s_groundMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "Default_small" }); } } private static void SpawnEffect(string name, Vector3 position, Quaternion rotation) { //IL_006a: 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) if (!s_effects.TryGetValue(name, out var value)) { value = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); s_effects[name] = value; if ((Object)(object)value == (Object)null) { RogueItems.Warn("effect " + name, "Effect " + name + " is missing from this game version; Shadowstep plays without it."); } } if ((Object)(object)value != (Object)null) { Object.Instantiate<GameObject>(value, position, rotation); } } } } namespace ElPopeAdventures.Rogue.Patches { [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class ObjectDBAwake { private static void Postfix(ObjectDB __instance) { try { RogueItems.RegisterInObjectDB(__instance); } catch (Exception ex) { RogueModule.Log.LogError((object)("Adding the rogue items failed; they are unavailable this session. " + ex)); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] internal static class ObjectDBCopyOtherDB { private static void Postfix(ObjectDB __instance) { try { RogueItems.RegisterInObjectDB(__instance); } catch (Exception ex) { RogueModule.Log.LogError((object)("Adding the rogue items failed; they are unavailable this session. " + ex)); } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetSceneAwake { private static void Postfix(ZNetScene __instance) { try { RogueItems.RegisterInScene(__instance); } catch (Exception ex) { RogueModule.Log.LogError((object)("Registering the rogue items with the world failed. " + ex)); } } } [HarmonyPatch(typeof(Player), "ConsumeItem")] internal static class PlayerConsumeItem { private static bool Prefix(Player __instance, ItemData item, ref bool __result) { try { if (RogueClass.RefuseTome(__instance, item)) { __result = false; return false; } } catch (Exception ex) { RogueModule.Log.LogWarning((object)("Shadowstone check failed: " + ex.Message)); } return true; } private static void Postfix(Player __instance, ItemData item, bool __result) { if (!__result) { return; } try { RogueClass.OnConsumed(__instance, item); } catch (Exception ex) { RogueModule.Log.LogError((object)("Becoming a Rogue failed: " + ex)); } } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Recipe), typeof(bool), typeof(int), typeof(int) })] internal static class PlayerHaveRequirementsRecipe { private static bool Prefix(Player __instance, Recipe recipe, ref bool __result) { try { if (RogueClass.DaggersLocked(__instance) && RogueItems.IsRogueOnlyRecipe(recipe)) { __result = false; return false; } } catch (Exception ex) { RogueModule.Log.LogWarning((object)("Dagger recipe check failed: " + ex.Message)); } return true; } } [HarmonyPatch(typeof(Player), "GetAvailableRecipes")] internal static class PlayerGetAvailableRecipes { private static void Postfix(Player __instance, ref List<Recipe> available) { try { if (available != null && RogueClass.DaggersLocked(__instance)) { available.RemoveAll(RogueItems.IsRogueOnlyRecipe); } } catch (Exception ex) { RogueModule.Log.LogWarning((object)("Dagger recipe list check failed: " + ex.Message)); } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] internal static class HumanoidStartAttack { private static bool Prefix(Humanoid __instance, bool secondaryAttack, ref bool __result) { try { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((val != null && RogueClass.RefuseDagger(val)) || Shadowstep.BeforeStartAttack(__instance, secondaryAttack)) { __result = false; return false; } } catch (Exception ex) { RogueModule.Log.LogWarning((object)("Dagger attack check failed: " + ex.Message)); } return true; } private static void Postfix(Humanoid __instance, bool __result) { try { Shadowstep.AfterStartAttack(__instance, __result); } catch (Exception ex) { RogueModule.Log.LogError((object)("Shadowstep failed: " + ex)); } } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] internal static class AttackOnAttackTrigger { private static void Postfix(Attack __instance) { try { Shadowstep.OnTrigger(__instance); } catch (Exception ex) { RogueModule.Log.LogError((object)("Shadowstep strike failed: " + ex)); } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class CharacterDamage { private static void Prefix(HitData hit) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 try { if (hit != null && (int)hit.m_skill == 2 && hit.m_backstabBonus > 1f) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && RogueClass.IsRogue(val)) { hit.m_backstabBonus *= 1f + Settings.SneakAttackBonus; } } } catch (Exception ex) { RogueModule.Log.LogWarning((object)("Sneak attack bonus failed: " + ex.Message)); } } } } namespace ElPopeAdventures.Masterwork { internal static class GlowFx { private const string TemplateItem = "SwordIron"; private const string TemplateName = "UpgraderGlow"; private const float HandGlowRadius = 0.25f; private static GameObject s_template; private static bool s_templateMissing; internal static void OnAttach(VisEquipment visuals, GameObject instance, int itemHash, int quality, bool backAttach) { if (!Settings.Enabled || !Settings.Glow || (Object)(object)instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemHash); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); ItemData item = (((Object)(object)val != (Object)null) ? val.m_itemData : null); GearKind gearKind = Masterwork.KindOf(item); if ((gearKind != GearKind.Weapon && gearKind != GearKind.Shield) || !Masterwork.Is(item, quality) || (Object)(object)instance.GetComponentInChildren<ParticleIntensityScaler>(true) != (Object)null) { return; } GameObject val2 = Template(); if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)instance.GetComponentInChildren<SkinnedMeshRenderer>(true) != (Object)null && !backAttach) { AddHandGlow(instance, val2, visuals.m_rightHand, quality); AddHandGlow(instance, val2, visuals.m_leftHand, quality); } else { AddBoxGlow(instance, val2, quality); } } } private static void AddHandGlow(GameObject instance, GameObject template, Transform hand, int quality) { //IL_002a: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hand == (Object)null)) { GameObject val = Spawn(instance.transform, template); val.AddComponent<FollowTransform>().Target = hand; val.transform.SetPositionAndRotation(hand.position, hand.rotation); ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ShapeModule shape = componentsInChildren[i].shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.25f; } Light(val, quality); } } private static void AddBoxGlow(GameObject instance, GameObject template, int quality) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) Bounds? val = null; Renderer[] componentsInChildren = instance.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (!(val2 is ParticleSystemRenderer)) { if (val.HasValue) { Bounds value = val.Value; ((Bounds)(ref value)).Encapsulate(val2.bounds); val = value; } else { val = val2.bounds; } } } if (val.HasValue) { GameObject val3 = Spawn(instance.transform, template); Transform transform = instance.transform; Transform transform2 = val3.transform; Bounds value2 = val.Value; transform2.position = ((Bounds)(ref value2)).center; Vector3 lossyScale = transform.lossyScale; value2 = val.Value; Vector3 size = ((Bounds)(ref value2)).size; Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(size.x / Mathf.Max(0.01f, lossyScale.x), size.y / Mathf.Max(0.01f, lossyScale.y), size.z / Mathf.Max(0.01f, lossyScale.z)); ParticleSystem[] componentsInChildren2 = val3.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ShapeModule shape = componentsInChildren2[i].shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref shape)).position = Vector3.zero; ((ShapeModule)(ref shape)).rotation = Vector3.zero; ((ShapeModule)(ref shape)).scale = Vector3.Max(val4 * 0.8f, Vector3.one * 0.05f); } Light(val3, quality); } } private static GameObject Spawn(Transform parent, GameObject template) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(template, parent, false); ((Object)obj).name = "UpgraderGlow"; obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.SetActive(true); return obj; } private static void Light(GameObject glow, int quality) { ParticleIntensityScaler[] componentsInChildren = glow.GetComponentsInChildren<ParticleIntensityScaler>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].SetQuality(quality); } } private static GameObject Template() { if ((Object)(object)s_template != (Object)null || s_templateMissing) { return s_template; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SwordIron"); Transform val = (((Object)(object)itemPrefab != (Object)null) ? Find(itemPrefab.transform, "UpgraderGlow") : null); if ((Object)(object)val == (Object)null) { s_templateMissing = true; MasterworkModule.Log.LogWarning((object)"The game's upgrade glow was not found; shields and dual weapons won't glow."); return null; } s_template = ((Component)val).gameObject; return s_template; } private static Transform Find(Transform parent, string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown foreach (Transform item in parent) { Transform val = item; if (((Object)val).name == name) { return val; } Transform val2 = Find(val, name); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } } internal enum GearKind { None, Weapon, Shield, Armor } internal static class Masterwork { internal static GearKind KindOf(ItemData item) { //IL_0023: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected I4, but got Unknown switch (item?.m_shared?.m_itemType) { case (ItemType)0L: case (ItemType)1L: case (ItemType)11L: case (ItemType)12L: case (ItemType)16L: case (ItemType)19L: return GearKind.Weapon; case (ItemType)2L: return GearKind.Shield; case (ItemType)3L: case (ItemType)4L: case (ItemType)8L: case (ItemType)14L: return GearKind.Armor; default: return GearKind.None; } } internal static bool Is(ItemData item, int quality) { if (item?.m_shared != null && item.m_shared.m_maxQuality > 1 && quality >= item.m_shared.m_maxQuality) { return KindOf(item) != GearKind.None; } return false; } internal static bool Is(ItemData item, int quality, GearKind kind) { if (Settings.Enabled && Is(item, quality)) { return KindOf(item) == kind; } return false; } internal static string Describe(ItemData item) { return KindOf(item) switch { GearKind.Weapon => $"+{Settings.DamageBonus * 100f:0}% damage, {Settings.CritChance * 100f:0}% chance of a critical hit " + $"(x{Settings.CritMultiplier:0.#} damage)", GearKind.Shield => $"+{Settings.BlockBonus * 100f:0}% block power", GearKind.Armor => $"+{Settings.ArmorBonus * 100f:0}% armour, +{Settings.RegenPerPiece * 100f:0}% health regeneration", _ => "", }; } internal static float RegenMultiplier(Player player) { if (!Settings.Enabled || Settings.RegenPerPiece <= 0f || (Object)(object)player == (Object)null) { return 1f; } int num = 0; foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems()) { if (Is(equippedItem, equippedItem.m_quality) && KindOf(equippedItem) == GearKind.Armor) { num++; } } return 1f + (float)num * Settings.RegenPerPiece; } } internal sealed class MasterworkModule : IModule { internal static readonly ManualLogSource Log = Logger.CreateLogSource("ElPopeAdventures.Masterwork"); private ConfigEntry<bool> _glow; private ConfigEntry<float> _damage; private ConfigEntry<float> _critChance; private ConfigEntry<float> _critMultiplier; private ConfigEntry<float> _block; private ConfigEntry<float> _armor; private ConfigEntry<float> _regen; public string Name => "Masterwork"; public string Description => "Gear upgraded to its maximum level glows and gets a bonus: damage and critical hits for weapons, block power for shields, armour and health regeneration for armour."; public Type[] PatchClasses { get; } = new Type[8] { typeof(ItemDataGetDamage), typeof(ItemDataGetArmor), typeof(ItemDataGetBaseBlockPower), typeof(ItemDataGetTooltip), typeof(SEManModifyHealthRegen), typeof(ElPopeAdventures.Masterwork.Patches.CharacterDamage), typeof(ParticleIntensityScalerSetQuality), typeof(ElPopeAdventures.Masterwork.Patches.VisEquipmentAttachItem) }; public void Initialize() { } public void Bind(ConfigFile config) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown _glow = config.Bind<bool>("Masterwork", "Glow", true, "Masterwork weapons and shields glow (in your hands, on your back and on the ground)."); _damage = config.Bind<float>("Masterwork", "WeaponDamageBonus", 0.1f, new ConfigDescription("Extra damage of masterwork weapons, bows, staffs and tools (0.1 = +10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _critChance = config.Bind<float>("Masterwork", "CriticalHitChance", 0.1f, new ConfigDescription("Chance that a hit on a creature with a masterwork weapon is a critical hit (0.1 = 10%). 0 turns critical hits off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _critMultiplier = config.Bind<float>("Masterwork", "CriticalHitMultiplier", 2f, new ConfigDescription("Damage multiplier of a critical hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); _block = config.Bind<float>("Masterwork", "ShieldBlockBonus", 0.2f, new ConfigDescription("Extra block power of masterwork shields (0.2 = +20%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _armor = config.Bind<float>("Masterwork", "ArmorBonus", 0.1f, new ConfigDescription("Extra armour of masterwork armour pieces and capes (0.1 = +10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); _regen = config.Bind<float>("Masterwork", "HealthRegenPerArmorPiece", 0.05f, new ConfigDescription("Extra health regeneration for each masterwork armour piece or cape you wear (0.05 = +5% each).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); PullSettings(); } public void OnSettingChanged() { PullSettings(); } public void Update() { } private void PullSettings() { Settings.Glow = _glow.Value; Settings.DamageBonus = _damage.Value; Settings.CritChance = _critChance.Value; Settings.CritMultiplier = _critMultiplier.Value; Settings.BlockBonus = _block.Value; Settings.ArmorBonus = _armor.Value; Settings.RegenPerPiece = _regen.Value; } } internal static class Settings { internal static bool Enabled = true; internal static bool Glow = true; internal static float DamageBonus = 0.1f; internal static float CritChance = 0.1f; internal static float CritMultiplier = 2f; internal static float BlockBonus = 0.2f; internal static float ArmorBonus = 0.1f; internal static float RegenPerPiece = 0.05f; } } namespace ElPopeAdventures.Masterwork.Patches { [HarmonyPatch(typeof(ItemData), "GetDamage", new Type[] { typeof(int), typeof(float) })] internal static class ItemDataGetDamage { private static void Postfix(ItemData __instance, int quality, ref DamageTypes __result) { if (Masterwork.Is(__instance, quality, GearKind.Weapon)) { ((DamageTypes)(ref __result)).Modify(1f + Settings.DamageBonus); } } } [HarmonyPatch(typeof(ItemData), "GetArmor", new Type[] { typeof(int), typeof(float) })] internal static class ItemDataGetArmor { private static void Postfix(ItemData __instance, int quality, ref float __result) { if (Masterwork.Is(__instance, quality, GearKind.Armor)) { __result *= 1f + Settings.ArmorBonus; } } } [HarmonyPatch(typeof(ItemData), "GetBaseBlockPower", new Type[] { typeof(int) })] internal static class ItemDataGetBaseBlockPower { private static void Postfix(ItemData __instance, int quality, ref float __result) { if (Masterwork.Is(__instance, quality, GearKind.Shield)) { __result *= 1f + Settings.BlockBonus; } } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class ItemDataGetTooltip { private static void Postfix(ItemData item, int qualityLevel, ref string __result) { try { if (Settings.Enabled && Masterwork.Is(item, qualityLevel)) { __result = __result + "\n<color=#FFB84D>Masterwork</color>: " + Masterwork.Describe(item); } } catch (Exception ex) { MasterworkModule.Log.LogWarning((object)("Masterwork tooltip failed: " + ex.Message)); } } } [HarmonyPatch(typeof(SEMan), "ModifyHealthRegen")] internal static class SEManModifyHealthRegen { private static readonly FieldRef<SEMan, Character> s_character = AccessTools.FieldRefAccess<SEMan, Character>("m_character"); private static void Postfix(SEMan __instance, ref float regenMultiplier) { try { Character obj = s_character.Invoke(__instance); Player val = (Player)(object)((obj is Player) ? obj : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { regenMultiplier *= Masterwork.RegenMultiplier(val); } } catch (Exception ex) { MasterworkModule.Log.LogWarning((object)("Masterwork regeneration failed: " + ex.Message)); } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class CharacterDamage { private static void Prefix(Character __instance, HitData hit) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) try { if (hit == null || Settings.CritChance <= 0f) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)__instance == (Object)(object)val) { return; } ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (currentWeapon != null && Masterwork.Is(currentWeapon, currentWeapon.m_quality, GearKind.Weapon) && hit.m_skill == currentWeapon.m_shared.m_skillType && !(Random.value >= Settings.CritChance)) { ((DamageTypes)(ref hit.m_damage)).Modify(Settings.CritMultiplier); EffectList critHitEffects = __instance.m_critHitEffects; if (critHitEffects != null) { critHitEffects.Create(hit.m_point, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } DamageText instance = DamageText.instance; if (instance != null) { instance.ShowText((TextType)7, hit.m_point + Vector3.up * 0.6f, "Critical!", false); } } } catch (Exception ex) { MasterworkModule.Log.LogWarning((object)("Masterwork critical hit failed: " + ex.Message)); } } } [HarmonyPatch(typeof(ParticleIntensityScaler), "SetQuality")] internal static class ParticleIntensityScalerSetQuality { private static void Prefix(ParticleIntensityScaler __instance, ref int quality) { if (Settings.Enabled && Settings.Glow && quality > 1 && quality >= __instance.maxQuality) { quality++; } } } [HarmonyPatch(typeof(VisEquipment), "AttachItem")] internal static class VisEquipmentAttachItem { private static void Postfix(VisEquipment __instance, GameObject __result, int itemHash, bool backAttach, int quality) { try { GlowFx.OnAttach(__instance, __result, itemHash, quality, backAttach); } catch (Exception ex) { MasterworkModule.Log.LogWarning((object)("Masterwork glow failed: " + ex.Message)); } } } } namespace ElPopeAdventures.Mage { internal static class ArmorLooks { private static readonly string[] s_colorTextures = new string[3] { "_MainTex", "_ChestTex", "_LegsTex" }; private static readonly Dictionary<(int, int), Material> s_materials = new Dictionary<(int, int), Material>(); private static readonly Dictionary<(int, int), Texture2D> s_textures = new Dictionary<(int, int), Texture2D>(); private static readonly Dictionary<(int, int), Sprite> s_icons = new Dictionary<(int, int), Sprite>(); internal static void Apply(ItemDrop item, int tier) { ArmorPalette palette = MageContent.ArmorPalettes[tier]; Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { sharedMaterials[j] = Recolored(sharedMaterials[j], tier, palette); } val.sharedMaterials = sharedMaterials; } SharedData shared = item.m_itemData.m_shared; shared.m_armorMaterial = Recolored(shared.m_armorMaterial, tier, palette); if (shared.m_icons != null && shared.m_icons.Length != 0) { Sprite[] array = (Sprite[])(object)new Sprite[shared.m_icons.Length]; for (int k = 0; k < array.Length; k++) { array[k] = RecoloredIcon(shared.m_icons[k], tier, palette); } shared.m_icons = array; } } private static Material Recolored(Material source, int tier, ArmorPalette palette) { //IL_0034: 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_0057: Expected O, but got Unknown //IL_0059: 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) if ((Object)(object)source == (Object)null) { return null; } (int, int) key = (((Object)source).GetInstanceID(), tier); if (s_materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Material val = new Material(source) { name = ((Object)source).name + "_" + MageContent.ArmorSetNames[tier] }; ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x20); string[] array = s_colorTextures; foreach (string text in array) { if (val.HasProperty(text)) { Texture texture = val.GetTexture(text); Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (val2 != null) { val.SetTexture(text, (Texture)(object)RecoloredTexture(val2, tier, palette)); } } } s_materials[key] = val; return val; } private static Texture2D RecoloredTexture(Texture2D source, int tier, ArmorPalette palette) { //IL_003f: 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_0077: Unknown result type (might be due to invalid IL or missing references) (int, int) key = (((Object)source).GetInstanceID(), tier); if (!s_textures.TryGetValue(key, out var value) || (Object)(object)value == (Object)null) { value = Recolor((Texture)(object)source, new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), palette, mipmaps: true); ((Object)value).name = ((Object)source).name + "_" + MageContent.ArmorSetNames[tier]; ((Texture)value).wrapMode = ((Texture)source).wrapMode; ((Texture)value).filterMode = ((Texture)source).filterMode; s_textures[key] = value; } return value; } private static Sprite RecoloredIcon(Sprite source, int tier, ArmorPalette palette) { //IL_0035: 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) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } (int, int) key = (((Object)source).GetInstanceID(), tier); if (s_icons.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } Rect textureRect; try { textureRect = source.textureRect; } catch (Exception) { return source; } Texture2D val = Recolor((Texture)(object)source.texture, textureRect, palette, mipmaps: false); ((Object)val).name = ((Object)source).name + "_" + MageContent.ArmorSetNames[tier]; Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit); ((Object)val2).name = ((Object)val).name; ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x20); s_icons[key] = val2; return val2; } private static Texture2D Recolor(Texture source, Rect region, ArmorPalette palette, bool mipmaps) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TextureTools.Recolor(source, region, ((ArmorPalette)palette).Apply, mipmaps); } } internal readonly struct ArmorPalette { private readonly float _hue; private readonly float _saturation; private readonly float _value; private readonly float _leather; internal ArmorPalette(float hueDegrees, float saturation, float value, float leather) { _hue = hueDegrees / 360f; _saturation = saturation; _value = value; _leather = leather; } internal Color32 Apply(Color32 pixel) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_0103: Unknown result type (might be due to invalid IL or missing references) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(Color32.op_Implicit(pixel), ref num, ref num2, ref num3); float num4 = num * 360f; float num5 = Mathf.Min(num4, 360f - num4); float num6 = (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(18f, 35f, num5))) * Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.25f, 0.45f, num2)); float num7 = Mathf.Abs(num4 - 25f); float num8 = (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(15f, 30f, num7))) * Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.12f, 0.25f, num2)) * (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.55f, 0.7f, num2))) * _leather; float num9 = Mathf.Max(num6, num8); if (num9 <= 0f) { return pixel; } Color val = Color.HSVToRGB(_hue, Mathf.Clamp01(num2 * _saturation), Mathf.Clamp01(num3 * _value)); Color32 result = Color32.op_Implicit(Color.Lerp(Color32.op_Implicit(pixel), val, num9)); result.a = pixel.a; return result; } } internal static class MageClass { private const string ClassKey = "FrostMage.Class"; private const string ClassValue = "Mage"; private static readonly MethodInfo s_updateFood = AccessTools.Method(typeof(Player), "UpdateFood", new Type[2] { typeof(float), typeof(bool) }, (Type[])null); private static readonly List<string> s_bossKeys = new List<string>(); private static float s_nextRefusal; internal static bool IsMage(Player player) { if ((Object)(object)player != (Object)null && player.m_customData != null && player.m_customData.TryGetValue("FrostMage.Class", out var value)) { return value == "Mage"; } return false; } internal static bool StaffsLocked(Player player) { if (Settings.StaffsRequireMage && (Object)(object)player != (Object)null) { return !IsMage(player); } return false; } internal static bool RefuseStaff(Player player) { if ((Object)(object)player != (Object)(object)Player.m_localPlayer || !StaffsLocked(player) || !MageItems.IsStaff(((Humanoid)player).GetCurrentWeapon())) { return false; } if (Time.time >= s_nextRefusal) { s_nextRefusal = Time.time + 2f; ((Character)player).Message((MessageType)2, "Only a Mage can use this staff. Read a Mage Tome first.", 0, (Sprite)null, false); } return true; } internal static float BonusMana(Player player) { if (!IsMage(player)) { return 0f; } return Settings.BaseMana + Settings.ManaPerBoss * (float)BossesDefeated(player); } internal static void FindBosses(ZNetScene scene) { s_bossKeys.Clear(); foreach (GameObject prefab in scene.m_prefabs) { Character val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null); if ((Object)(object)val != (Object)null && val.m_boss && !string.IsNullOrEmpty(val.m_defeatSetGlobalKey) && !s_bossKeys.Contains(val.m_defeatSetGlobalKey)) { s_bossKeys.Add(val.m_defeatSetGlobalKey); } } MageModule.Log.LogInfo((object)string.Format("Mage mana grows with {0} bosses: {1}.", s_bossKeys.Count, string.Join(", ", s_bossKeys.ToArray()))); } private static int BossesDefeated(Player player) { ZoneSystem instance = ZoneSystem.instance; int num = 0; foreach (string s_bossKey in s_bossKeys) { if (((Object)(object)instance != (Object)null && instance.GetGlobalKey(s_bossKey)) || ((Humanoid)player).HaveUniqueKey(s_bossKey)) { num++; } } return num; } internal static bool RefuseTome(Player player, ItemData item) { if (!MageItems.IsTome(item) || !IsMage(player)) { return false; } ((Character)player).Message((MessageType)2, "You are already a Mage.", 0, (Sprite)null, false); return true; } internal static bool RefuseCocktail(Player player, ItemData item) { if (!MageItems.IsCocktail(item) || ((Character)player).GetMaxEitr() > 0f) { return false; } ((Character)player).Message((MessageType)2, "You have no mana to restore. Read a Mage Tome first.", 0, (Sprite)null, false); return true; } internal static void OnConsumed(Player player, ItemData item) { if (MageItems.IsTome(item) && !IsMage(player)) { player.m_customData["FrostMage.Class"] = "Mage"; float num = BonusMana(player); try { s_updateFood?.Invoke(player, new object[2] { 0f, true }); ((Character)player).AddEitr(num); } catch (Exception ex) { MageModule.Log.LogWarning((object)("Mana pool will appear within a second (" + ex.Message + ").")); } ((Character)player).Message((MessageType)2, $"You have awakened as a Mage! ({num:0} mana)", 0, (Sprite)null, false); MageModule.Log.LogInfo((object)(player.GetPlayerName() + " became a Mage.")); } } } internal enum ItemKind { Tome, Staff, Cocktail, Armor } internal enum ArmorSlot { Hood, Robe, Trousers } internal sealed class School { internal readonly string Name; internal readonly (string Prefab, int NativeTier)[] Sources; internal readonly Func<DamageTypes, DamageTypes> Convert; internal School(string name, (string, int)[] sources, Func<DamageTypes, DamageTypes> convert = null) { Name = name; Sources = sources; Convert = convert; } } internal sealed class MageItemDef { internal string Id; internal string Name; internal string Description; internal ItemKind Kind; internal int Tier; internal School Schoo