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 Cleaverang v1.0.6
plugins/Cleaverang.dll
Decompiled 4 days agousing 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.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dolso; using EntityStates; using HG; using HG.Reflection; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.ContentManagement; using RoR2.Projectile; using RoR2.Skills; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Cleaverang")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Cleaverang")] [assembly: AssemblyTitle("Cleaverang")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Dolso { internal static class log { private static readonly ManualLogSource logger = Logger.CreateLogSource(Assembly.GetExecutingAssembly().GetName().Name); [Conditional("DEBUG")] internal static void debug(object data) { logger.LogDebug(data); } internal static void info(object data) { logger.LogInfo(data); } internal static void message(object data) { logger.LogMessage(data); } internal static void warning(object data) { logger.LogWarning(data); } internal static void error(object data) { logger.LogError(data); } internal static void fatal(object data) { logger.LogFatal(data); } internal static void LogError(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failure, skipping: {data}\n{c}"); } internal static void LogErrorCaller(this ILCursor c, object data) { logger.LogError((object)$"ILCursor failed in {new StackFrame(1).GetMethod().Name}, skipping: {data}\n{c}"); } } internal static class HookManager { internal delegate bool ConfigEnabled<T>(T configValue); internal class HookedConfig<T> { private readonly ConfigEnabled<T> enabled; private readonly IDetour detour; internal HookedConfig(ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, IDetour detour) { this.enabled = enabled; this.detour = detour; if (configEntry != null) { configEntry.SettingChanged += ConfigChanged; ConfigChanged(configEntry, null); } else { detour.Apply(); } } private void ConfigChanged(object sender, EventArgs args) { if (!detour.IsValid) { return; } if (enabled(((ConfigEntry<T>)sender).Value)) { if (!detour.IsApplied) { detour.Apply(); } } else if (detour.IsApplied) { detour.Undo(); } } } internal const BindingFlags allFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly List<IDisposable> detours = new List<IDisposable>(); private static readonly ConfigEnabled<bool> boolConfigEnabled = BoolEnabled; private static ILHookConfig ilHookConfig = new ILHookConfig { ManualApply = true }; private static HookConfig onHookConfig = new HookConfig { ManualApply = true }; internal static int Hook(Type typeFrom, string fromMethod, Manipulator ilHook) { return Hook(GetMethod(typeFrom, fromMethod), ilHook); } internal static int Hook(Delegate fromMethod, Manipulator ilHook) { return Hook(fromMethod.Method, ilHook); } internal static int Hook(MethodBase fromMethod, Manipulator ilHook) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown try { ILHook val = new ILHook(fromMethod, ilHook, ref ilHookConfig); detours.Add((IDisposable)val); val.Apply(); } catch (Exception e) { e.LogHookError(fromMethod, ((Delegate)(object)ilHook).Method); return 8; } return 0; } internal static int Hook(Type typeFrom, string fromMethod, Delegate onHook) { return Hook(GetMethod(typeFrom, fromMethod), onHook.Method, onHook.Target); } internal static int Hook(Delegate fromMethod, Delegate onHook) { return Hook(fromMethod.Method, onHook.Method, onHook.Target); } internal static int Hook(MethodBase fromMethod, Delegate onHook) { return Hook(fromMethod, onHook.Method, onHook.Target); } internal static int Hook(MethodBase fromMethod, MethodInfo onHook, object target = null) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown try { Hook val = new Hook(fromMethod, onHook, target, ref onHookConfig); detours.Add((IDisposable)val); val.Apply(); } catch (Exception e) { e.LogHookError(fromMethod, onHook); return 8; } return 0; } internal static int HookConfig(this ConfigEntry<bool> configEntry, Type typeFrom, string fromMethod, Delegate hook) { return configEntry.HookConfig(boolConfigEnabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static int HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, Delegate hook) { return configEntry.HookConfig(boolConfigEnabled, fromMethod, hook.Method, hook.Target); } internal static int HookConfig(this ConfigEntry<bool> configEntry, MethodBase fromMethod, MethodInfo hook) { return configEntry.HookConfig(boolConfigEnabled, fromMethod, hook); } internal static int HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, Type typeFrom, string fromMethod, Delegate hook) { return configEntry.HookConfig(enabled, GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static int HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, Delegate hook) { return configEntry.HookConfig(enabled, fromMethod, hook.Method, hook.Target); } internal static int HookConfig<T>(this ConfigEntry<T> configEntry, ConfigEnabled<T> enabled, MethodBase fromMethod, MethodInfo hook, object target = null) { try { IDetour val = ManualDetour(fromMethod, hook, target); if (val == null) { return 8; } new HookedConfig<T>(configEntry, enabled, val); return 0; } catch (Exception e) { e.LogHookError(fromMethod, hook); return 8; } } internal static IDetour ManualDetour(Type typeFrom, string fromMethod, Delegate hook) { return ManualDetour(GetMethod(typeFrom, fromMethod), hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, Delegate hook) { return ManualDetour(fromMethod, hook.Method, hook.Target); } internal static IDetour ManualDetour(MethodBase fromMethod, MethodInfo hook, object target = null) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown try { ParameterInfo[] parameters = hook.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ILContext)) { return (IDetour)new ILHook(fromMethod, (Manipulator)hook.CreateDelegate(typeof(Manipulator)), ref ilHookConfig); } return (IDetour)new Hook(fromMethod, hook, target, ref onHookConfig); } catch (Exception e) { e.LogHookError(fromMethod, hook); return null; } } internal static MethodInfo GetMethod(Type typeFrom, string methodName) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo[] array = (from a in typeFrom.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where a.Name == methodName select a).ToArray(); switch (array.Length) { case 1: return array[0]; case 0: log.error($"Failed to find method: {typeFrom}::{methodName}"); return null; default: { string text = $"{array.Length} ambiguous matches found for {typeFrom}::{methodName}, may be incorrect"; MethodInfo[] array2 = array; for (int num = 0; num < array2.Length; num++) { text = text + "\n" + array2[num]; } log.warning(text); return array[0]; } } } internal static MethodInfo GetMethod(Type typeFrom, string methodName, params Type[] parameters) { if (typeFrom == null || methodName == null) { log.error($"Null argument in GetMethod: type={typeFrom}, name={methodName}"); return null; } MethodInfo? method = typeFrom.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, parameters, null); if (method == null) { log.error($"Failed to find method: {typeFrom}::{methodName}_{parameters.Length}"); } return method; } internal static void SetPriority(string[] before_il = null, string[] before_on = null, string[] after_il = null, string[] after_on = null) { ilHookConfig.Before = before_il; onHookConfig.Before = before_on; ilHookConfig.After = after_il; onHookConfig.After = after_on; } internal static void DisposeAll() { for (int num = detours.Count - 1; num >= 0; num--) { try { IDisposable disposable = detours[num]; detours.RemoveAt(num); disposable.Dispose(); } catch (Exception) { } } } internal static void LogHookError(this Exception e, MethodBase fromMethod, MethodInfo hook) { log.error((fromMethod == null) ? $"null from-method for hook: {hook.Name}\n{e}" : $"Failed to hook: {fromMethod.DeclaringType}::{fromMethod.Name} - {hook.Name}\n{e}"); } private static bool BoolEnabled(bool configValue) { return configValue; } } internal static class Utilities { private static GameObject _prefabParent; internal static GameObject CreatePrefab(GameObject gameObject, string name = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_prefabParent)) { _prefabParent = new GameObject("DolsoPrefabs"); Object.DontDestroyOnLoad((Object)(object)_prefabParent); ((Object)_prefabParent).hideFlags = (HideFlags)61; _prefabParent.SetActive(false); } GameObject val = Object.Instantiate<GameObject>(gameObject, _prefabParent.transform); if (name != null) { ((Object)val).name = name; } return val; } } internal static class RiskofOptions { internal const string RooGuid = "com.rune580.riskofoptions"; internal static bool enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining)] internal static void SetSprite(Sprite sprite) { ModSettingsManager.SetModIcon(sprite); } internal static void SetSpriteDefaultIcon() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { string fullName = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).FullName; Texture2D val = new Texture2D(256, 256); if (ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(fullName, "icon.png")))) { ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f))); } else { log.error("Failed to load icon.png"); } } catch (Exception ex) { log.error("Failed to load icon.png\n" + ex); } } internal static void AddOption(ConfigEntryBase entry) { AddOption(entry, string.Empty, string.Empty); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddOption(ConfigEntryBase entry, string categoryName = "", string name = "", bool restartRequired = false) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01ae: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00cf: 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_00bf: Expected O, but got Unknown //IL_00ba: 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_00aa: Expected O, but got Unknown //IL_00a5: 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_0095: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) Type settingType = entry.SettingType; object obj; if (!(settingType == typeof(float))) { obj = ((!(settingType == typeof(string))) ? ((!(settingType == typeof(bool))) ? ((!(settingType == typeof(int))) ? ((!(settingType == typeof(Color))) ? ((!(settingType == typeof(KeyboardShortcut))) ? ((object)((!settingType.IsEnum) ? ((ChoiceOption)null) : new ChoiceOption(entry, new ChoiceConfig()))) : ((object)new KeyBindOption((ConfigEntry<KeyboardShortcut>)(object)entry, new KeyBindConfig()))) : ((object)new ColorOption((ConfigEntry<Color>)(object)entry, new ColorOptionConfig()))) : ((object)new IntFieldOption((ConfigEntry<int>)(object)entry, new IntFieldConfig()))) : ((object)new CheckBoxOption((ConfigEntry<bool>)(object)entry, new CheckBoxConfig()))) : ((object)new StringInputFieldOption((ConfigEntry<string>)(object)entry, new InputFieldConfig { submitOn = (SubmitEnum)6, lineType = (LineType)0 }))); } else if (entry.Description.AcceptableValues is AcceptableValueRange<float>) { obj = (object)new SliderOption((ConfigEntry<float>)(object)entry, new SliderConfig { min = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MinValue, max = ((AcceptableValueRange<float>)(object)entry.Description.AcceptableValues).MaxValue, FormatString = "{0:f2}", description = entry.DescWithDefault("{0:f2}") }); } else { ConfigEntry<float> obj2 = (ConfigEntry<float>)(object)entry; FloatFieldConfig val = new FloatFieldConfig(); ((NumericFieldConfig<float>)val).FormatString = "{0:f2}"; ((BaseOptionConfig)val).description = entry.DescWithDefault("{0:f2}"); obj = (object)new FloatFieldOption(obj2, val); } BaseOption val2 = (BaseOption)obj; if (val2 == null) { return; } BaseOptionConfig config = val2.GetConfig(); config.category = categoryName; config.name = name; config.restartRequired = restartRequired; if (config.description == "") { config.description = entry.DescWithDefault(); } try { ModSettingsManager.AddOption(val2); } catch (Exception arg) { log.error($"AddOption {entry.Definition} failed\n{arg}"); } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddOption(ConfigEntry<float> entry, float min, float max, string format = "{0:f2}", string categoryName = "") { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(entry, new SliderConfig { min = min, max = max, FormatString = format, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault(format) })); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddIntSlider(ConfigEntry<int> entry, int min, int max, string categoryName = "") { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig { min = min, max = max, category = categoryName, description = ((ConfigEntryBase)(object)entry).DescWithDefault() })); } private static string DescWithDefault(this ConfigEntryBase entry, string format = "{0}") { return string.Format("{1}\n[Default: " + format + "]", entry.DefaultValue, entry.Description.Description); } } } namespace Cleaverang { internal class Config { private static ConfigFile configFile; private static ConfigEntry<string> version; internal static ConfigEntry<float> damage; internal static ConfigEntry<float> bleedChance; internal static ConfigEntry<float> procCoef; internal static ConfigEntry<float> cooldown; internal static ConfigEntry<float> interval; internal static void DoConfig(ConfigFile bepConfigFile) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown configFile = bepConfigFile; damage = configFile.Bind<float>("Stats", "Damage", 0.8f, "Damage multiplier of hits"); bleedChance = configFile.Bind<float>("Stats", "Bleed Chance", 40f, new ConfigDescription("Bleed chance of boosted (from Yes Chef) Cleaverangs", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); procCoef = configFile.Bind<float>("Stats", "Proc Coefficient", 1f, "Proc coefficient of the repeated hits"); cooldown = configFile.Bind<float>("Stats", "Cooldown", 2.25f, "Cooldown of Cleaverang. For reference vanilla Dice cooldown is 1.75s"); interval = configFile.Bind<float>("Stats", "Attack Interval", 0.5f, "Interval between attacks"); version = configFile.Bind<string>("", "Config Version", "1.0.6", "Config version, if this is different from current version, resets config"); if (version.Value != "1.0.6") { configFile.Clear(); DoConfig(configFile); } else if (RiskofOptions.enabled) { DoRiskOfOptions(); } } internal static void DoRiskOfOptions() { RiskofOptions.AddOption(damage, 0f, 1.5f); RiskofOptions.AddOption(bleedChance, 0f, 100f, "{0:f0}"); RiskofOptions.AddOption(procCoef, 0f, 2f); RiskofOptions.AddOption(cooldown, 0.5f, 6f); RiskofOptions.AddOption(interval, 0f, 1.5f); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void ReloadConfig(ConCommandArgs args) { configFile.Reload(); Debug.Log((object)"Cleaverang config reloaded"); } } internal class Content : IContentPackProvider { private static AssetBundle assetBundle; internal static ContentPack contentPack; internal static GameObject cleaverangPrefab; internal static GameObject cleaverangBoostedPrefab; internal static SkillDef cSkillDef; internal static SkillDef cBoostedSkillDef; public string identifier => "dolso.Cleaverang"; private static string directory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args) { AssetBundleCreateRequest assetBundleRequest = AssetBundle.LoadFromFileAsync(Path.Combine(directory, "cleaverang")); yield return LoadAsync((AsyncOperation)(object)assetBundleRequest, args); assetBundle = assetBundleRequest.assetBundle; AssetBundleRequest serializableContentPack = assetBundle.LoadAssetAsync<SerializableContentPack>("Cleaverang ContentPack"); yield return LoadAsync((AsyncOperation)(object)serializableContentPack, args); Object asset = serializableContentPack.asset; contentPack = ((SerializableContentPack)((asset is SerializableContentPack) ? asset : null)).CreateContentPack(); yield return DoProjectiles(); yield return DoSkills(); if (RiskofOptions.enabled) { yield return DoRiskOfOptions(); } static IEnumerator LoadAsync(AsyncOperation request, LoadStaticContentAsyncArgs val) { while (!request.isDone) { val.ReportProgress(request.progress); yield return null; } } } public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args) { ContentPack.Copy(contentPack, args.output); yield break; } public IEnumerator FinalizeAsync(FinalizeAsyncArgs args) { yield break; } private static IEnumerator DoProjectiles() { AsyncOperationHandle<GameObject> sawAsync = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Saw/Sawmerang.prefab"); AsyncOperationHandle<GameObject> muzzleFlashAsync = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC2/Chef/MuzzleflashChefDiceReturn.prefab"); AsyncOperationHandle<BuffDef> chefBuffAsync = Addressables.LoadAssetAsync<BuffDef>((object)"RoR2/DLC2/Chef/Buffs/bdCookingChopped.asset"); AssetBundleRequest redMatAsync = assetBundle.LoadAssetAsync<Texture>("texSawmerangRedDiffuse"); yield return sawAsync; yield return muzzleFlashAsync; yield return chefBuffAsync; yield return redMatAsync; ThrowCleaverang.muzzleFlashPrefab = muzzleFlashAsync.Result; GameObject result = sawAsync.Result; GameObject obj = (cleaverangPrefab = contentPack.projectilePrefabs.Find("CleaverangProjectile")); GameObject val = (cleaverangBoostedPrefab = contentPack.projectilePrefabs.Find("CleaverangBoostedProjectile")); ProjectileController component = result.GetComponent<ProjectileController>(); ProjectileController component2 = obj.GetComponent<ProjectileController>(); ProjectileController component3 = val.GetComponent<ProjectileController>(); component2.ghostPrefabAddress = component.ghostPrefabAddress; component2.flightSoundLoop = (component3.flightSoundLoop = component.flightSoundLoop); component3.ghostPrefab = Utilities.CreatePrefab(component.ghostPrefabAddress.LoadAssetAsync().WaitForCompletion(), "CleaverangBoostedGhost"); MeshRenderer componentInChildren = component3.ghostPrefab.GetComponentInChildren<MeshRenderer>(); ((Renderer)componentInChildren).material = new Material(((Renderer)componentInChildren).material) { name = "matSawmerangRed", mainTexture = (Texture)/*isinst with value type is only supported in some contexts*/ }; BoomerangProjectile component4 = result.GetComponent<BoomerangProjectile>(); BoomerangProjectile component5 = obj.GetComponent<BoomerangProjectile>(); BoomerangProjectile component6 = val.GetComponent<BoomerangProjectile>(); component5.impactSpark = (component6.impactSpark = component4.impactSpark); ProjectileDotZone component7 = result.GetComponent<ProjectileDotZone>(); ProjectileDotZone component8 = obj.GetComponent<ProjectileDotZone>(); ProjectileDotZone component9 = val.GetComponent<ProjectileDotZone>(); component8.impactEffect = (component9.impactEffect = component7.impactEffect); component8.overlapProcCoefficient = (component9.overlapProcCoefficient = Config.procCoef.Value); ProjectileOverlapAttack component10 = result.GetComponent<ProjectileOverlapAttack>(); ProjectileOverlapAttack component11 = obj.GetComponent<ProjectileOverlapAttack>(); ProjectileOverlapAttack component12 = val.GetComponent<ProjectileOverlapAttack>(); component11.impactEffect = (component12.impactEffect = component10.impactEffect); ProjectileInflictTimedBuff component13 = obj.GetComponent<ProjectileInflictTimedBuff>(); ProjectileInflictTimedBuff component14 = val.GetComponent<ProjectileInflictTimedBuff>(); component13.buffDef = (component14.buffDef = chefBuffAsync.Result); sawAsync.Release(); } private static IEnumerator DoSkills() { AsyncOperationHandle<GameObject> chefBodyAsync = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC2/Chef/ChefBody.prefab"); yield return chefBodyAsync; cSkillDef = contentPack.skillDefs.Find("CleaverangSkillDef"); cBoostedSkillDef = contentPack.skillDefs.Find("CleaverangBoostedSkillDef"); cSkillDef.baseRechargeInterval = (cBoostedSkillDef.baseRechargeInterval = Config.cooldown.Value); cSkillDef.activationState = (cBoostedSkillDef.activationState = new SerializableEntityStateType(typeof(ThrowCleaverang))); contentPack.entityStateTypes.Add(new Type[1] { typeof(ThrowCleaverang) }); ref Variant[] variants = ref chefBodyAsync.Result.GetComponent<SkillLocator>().primary.skillFamily.variants; Variant val = new Variant { skillDef = cSkillDef }; ((Variant)(ref val)).viewableNode = new Node(cSkillDef.skillNameToken, false, (Node)null); ArrayUtils.ArrayAppend<Variant>(ref variants, ref val); } private static IEnumerator DoRiskOfOptions() { AssetBundleRequest sprite = assetBundle.LoadAssetAsync<Sprite>("CleaverangIcon"); yield return sprite; Object asset = sprite.asset; RiskofOptions.SetSprite((Sprite)(object)((asset is Sprite) ? asset : null)); } } internal static class Hooks { private static int cleaverangIndex; private static int cleaverangBoostedIndex; internal static void DoHooks() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown HookManager.Hook(typeof(ChefController), "OverrideYesChefSkillBySlot", (Delegate)new Func<Func<ChefController, SkillSlot, SkillStateOverrideData, bool>, ChefController, SkillSlot, SkillStateOverrideData, bool>(AddOverride_On_ChefController_OverrideYesChefSkillBySlot)); HookManager.Hook(typeof(GlobalEventManager), "ProcessHitEnemy", new Manipulator(SetBleed_IL_GlobalEventManager_OnHitEnemy)); HookManager.Hook(typeof(BoomerangProjectile), "Start", (Delegate)new Action<Action<BoomerangProjectile>, BoomerangProjectile>(SetVelocity_On_BoomerangProjectile_Start)); HookManager.Hook(typeof(BoomerangProjectile), "FixedUpdate", new Manipulator(ChangeFlightPath_IL_BoomerangProjectile_FixedUpdate)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnRoR2Loaded)); } private static void OnRoR2Loaded() { cleaverangIndex = ProjectileCatalog.FindProjectileIndex("CleaverangProjectile"); cleaverangBoostedIndex = ProjectileCatalog.FindProjectileIndex("CleaverangBoostedProjectile"); } private static bool AddOverride_On_ChefController_OverrideYesChefSkillBySlot(Func<ChefController, SkillSlot, SkillStateOverrideData, bool> orig, ChefController self, SkillSlot slot, SkillStateOverrideData skillOverrideData) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((int)slot == 0 && (Object)(object)self.skillLocator.primary.skillDef == (Object)(object)Content.cSkillDef) { skillOverrideData.primarySkillOverride = Content.cBoostedSkillDef; return true; } return orig(self, slot, skillOverrideData); } private static void SetBleed_IL_GlobalEventManager_OnHitEnemy(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); VariableDefinition val2 = ((IEnumerable<VariableDefinition>)val.Body.Variables).First((VariableDefinition a) => ((MemberReference)((VariableReference)a).VariableType).Name == typeof(CharacterMaster).Name); VariableDefinition val3 = ((IEnumerable<VariableDefinition>)val.Body.Variables).First((VariableDefinition a) => ((MemberReference)((VariableReference)a).VariableType).Name == typeof(BoomerangProjectile).Name); ILLabel branchFalse = null; int sawBleedIndex = -1; if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdsfld(a, typeof(Equipment), "Saw") }) && val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchBneUn(a, ref branchFalse) }) && val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchStloc(a, ref sawBleedIndex) })) { val.GotoLabel(branchFalse, (MoveType)1, false); val.Emit(OpCodes.Ldloc, val2); val.Emit(OpCodes.Ldloc, val3); val.Emit(OpCodes.Ldloca, sawBleedIndex); val.EmitDelegate<<>A{00000040}<CharacterMaster, BoomerangProjectile, int>>((<>A{00000040}<CharacterMaster, BoomerangProjectile, int>)delegate(CharacterMaster master, BoomerangProjectile boomerang, ref int sawBleed) { if (boomerang.projectileController != null) { int catalogIndex = boomerang.projectileController.catalogIndex; if (catalogIndex == cleaverangIndex) { sawBleed = 0; } else if (catalogIndex == cleaverangBoostedIndex) { sawBleed = (Util.CheckRoll(Config.bleedChance.Value, master) ? 1 : 0); } } }); } else { val.LogErrorCaller("saw bleed"); } } private static void SetVelocity_On_BoomerangProjectile_Start(Action<BoomerangProjectile> orig, BoomerangProjectile self) { //IL_002b: 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) orig(self); if (self.projectileController.catalogIndex == cleaverangBoostedIndex) { self.rigidbody.velocity = self.travelSpeed * ((Component)self).transform.forward; } } private static void ChangeFlightPath_IL_BoomerangProjectile_FixedUpdate(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0096: 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) ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchCallOrCallvirt(a, typeof(Rigidbody), "set_velocity") })) { ILLabel val2 = val.MarkLabel(); if (val.TryGotoPrev(new Func<Instruction, bool>[1] { (Instruction a) => ILPatternMatchingExt.MatchLdfld(a, typeof(BoomerangProjectile), "rigidbody") })) { val.EmitDelegate<Func<BoomerangProjectile, bool>>((Func<BoomerangProjectile, bool>)((BoomerangProjectile self) => self.projectileController.catalogIndex == cleaverangBoostedIndex)); val.Emit(OpCodes.Brtrue, (object)val2); val.Emit(OpCodes.Ldarg_0); return; } } val.LogErrorCaller(""); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dolso.Cleaverang", "Cleaverang", "1.0.6")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "dolso.Cleaverang"; internal const string Version = "1.0.6"; private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Config.DoConfig(((BaseUnityPlugin)this).Config); ConfigEvents(); Hooks.DoHooks(); ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(CollectContentPack); Language.collectLanguageRootFolders += CollectLanguageFolder; } private static void CollectContentPack(AddContentPackProviderDelegate addContentPackProvider) { addContentPackProvider.Invoke((IContentPackProvider)(object)new Content()); } private void CollectLanguageFolder(List<string> list) { list.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language")); } private static void ConfigEvents() { Config.cooldown.SettingChanged += delegate { Content.cSkillDef.baseRechargeInterval = Config.cooldown.Value; Content.cBoostedSkillDef.baseRechargeInterval = Config.cooldown.Value; }; Config.procCoef.SettingChanged += delegate { Content.cleaverangPrefab.GetComponent<ProjectileDotZone>().overlapProcCoefficient = Config.procCoef.Value; Content.cleaverangBoostedPrefab.GetComponent<ProjectileDotZone>().overlapProcCoefficient = Config.procCoef.Value; }; } } internal class ThrowCleaverang : BaseState { internal static GameObject muzzleFlashPrefab; private float baseDuration; private bool boosted; public override void OnEnter() { //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: 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_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) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: 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_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); boosted = ((EntityState)this).characterBody.HasBuff(Buffs.Boosted); if (boosted && NetworkServer.active) { ((EntityState)this).characterBody.RemoveBuff(Buffs.Boosted); } baseDuration = Config.interval.Value; float num = baseDuration / base.attackSpeedStat; ((BaseState)this).StartAimMode(num + 2f, false); if (boosted) { ((EntityState)this).PlayAnimation("Gesture, Override", "FireSliceAndDice", "FireSliceAndDice.playbackRate", num, 0f); ((EntityState)this).PlayAnimation("Gesture, Additive", "FireSliceAndDice", "FireSliceAndDice.playbackRate", num, 0f); Util.PlaySound("Play_chef_skill1_boosted_shoot", ((EntityState)this).gameObject); } else { ((EntityState)this).PlayAnimation("Gesture, Override", "FireDice", "FireDice.playbackRate", num, 0f); ((EntityState)this).PlayAnimation("Gesture, Additive", "FireDice", "FireDice.playbackRate", num, 0f); Util.PlaySound("Play_chef_skill1_shoot", ((EntityState)this).gameObject); } EffectManager.SimpleMuzzleFlash(muzzleFlashPrefab, ((Component)((EntityState)this).characterBody.aimOriginTransform).gameObject, "MouthMuzzle", false); if (((EntityState)this).isAuthority) { Ray aimRay = ((BaseState)this).GetAimRay(); Quaternion val = Util.QuaternionSafeLookRotation(((Ray)(ref aimRay)).direction); if (boosted) { GameObject cleaverangBoostedPrefab = Content.cleaverangBoostedPrefab; Quaternion val2 = Quaternion.AngleAxis(90f, ((Ray)(ref aimRay)).direction); Quaternion val3 = val * Quaternion.Euler(0f, 15f, 0f); FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val); FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3); val3 = val2 * val3; FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3); val3 = val2 * val3; FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3); val3 = val2 * val3; FireSingleProjectile(cleaverangBoostedPrefab, ((Ray)(ref aimRay)).origin, val3); } else { FireSingleProjectile(Content.cleaverangPrefab, ((Ray)(ref aimRay)).origin, val); } } } private void FireSingleProjectile(GameObject prefab, Vector3 origin, Quaternion rotation) { //IL_0007: 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_0018: 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) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) ProjectileManager.instance.FireProjectile(new FireProjectileInfo { projectilePrefab = prefab, position = origin, rotation = rotation, owner = ((EntityState)this).gameObject, damage = base.damageStat * Config.damage.Value, crit = Util.CheckRoll(base.critStat, ((EntityState)this).characterBody.master), force = 0f }); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= baseDuration / ((EntityState)this).characterBody.attackSpeed) { ((EntityState)this).outer.SetNextStateToMain(); } } public override void OnExit() { ChefController component = ((EntityState)this).GetComponent<ChefController>(); component.SetYesChefState(false); if (((EntityState)this).isAuthority) { component.ClearSkillOverrides(); } if (NetworkServer.active) { ((EntityState)this).characterBody.RemoveBuff(Buffs.boostedFireEffect); } ((EntityState)this).OnExit(); } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } }