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 NotHeretic v1.1.1
NotHeretic.dll
Decompiled 12 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.Heretic; using EntityStates.Vulture; using HG.GeneralSerializer; using KinematicCharacterController; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using NotHeretic.States; using R2API; using R2API.Utils; using RoR2; using RoR2.CharacterAI; using RoR2.Projectile; using RoR2.Skills; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NotHeretic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("NotHeretic")] [assembly: AssemblyTitle("NotHeretic")] [assembly: AssemblyVersion("1.1.1.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 NotHeretic { internal static class Asset { public static T Load<T>(string key) where T : Object { //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) T val = Addressables.LoadAssetAsync<T>((object)key).WaitForCompletion(); if (!Object.op_Implicit((Object)(object)val)) { NotHereticPlugin.Log.LogError((object)("Missing game asset: " + key)); } return val; } public static T Load<T>(AssetReferenceT<T> reference) where T : Object { //IL_001b: 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) if (reference == null || !((AssetReference)reference).RuntimeKeyIsValid()) { return default(T); } return Addressables.LoadAssetAsync<T>(((AssetReference)reference).RuntimeKey).WaitForCompletion(); } public static Sprite Icon(string textureKey, float? hue = null) { //IL_006e: 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) Texture2D val = Asset.Load<Texture2D>(textureKey); if (Object.op_Implicit((Object)(object)val) && hue.HasValue) { try { val = TextureTools.HueShift((Texture)(object)val, hue.Value); } catch (Exception ex) { NotHereticPlugin.Log.LogWarning((object)("Could not recolour " + textureKey + ", using it as is: " + ex.Message)); } } if (!Object.op_Implicit((Object)(object)val)) { return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } public static T EscObject<T>(string escKey, string fieldName) where T : Object { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) SerializedField? val = FindEscField(escKey, fieldName); if (!val.HasValue) { return default(T); } Object objectValue = val.Value.fieldValue.objectValue; return (T)(object)((objectValue is T) ? objectValue : null); } public static string EscString(string escKey, string fieldName, string fallback = "") { //IL_0016: 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) SerializedField? val = FindEscField(escKey, fieldName); string text = (val.HasValue ? val.Value.fieldValue.stringValue : null); if (!string.IsNullOrEmpty(text)) { return text; } return fallback; } private static SerializedField? FindEscField(string escKey, string fieldName) { //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_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_0051: 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) EntityStateConfiguration val = Addressables.LoadAssetAsync<EntityStateConfiguration>((object)escKey).WaitForCompletion(); if (!Object.op_Implicit((Object)(object)val)) { NotHereticPlugin.Log.LogWarning((object)("Missing entity state configuration: " + escKey)); return null; } SerializedField[] serializedFields = val.serializedFieldsCollection.serializedFields; foreach (SerializedField val2 in serializedFields) { if (val2.fieldName == fieldName) { return val2; } } NotHereticPlugin.Log.LogWarning((object)("Field " + fieldName + " not found in " + escKey)); return null; } } public class DisplayPose : MonoBehaviour { private static readonly int IsGrounded = Animator.StringToHash("isGrounded"); private static readonly int AimPitchCycle = Animator.StringToHash("aimPitchCycle"); private static readonly int AimYawCycle = Animator.StringToHash("aimYawCycle"); private Animator animator; private bool hasGrounded; private bool hasPitch; private bool hasYaw; private void LateUpdate() { if (!Object.op_Implicit((Object)(object)animator)) { animator = ((Component)this).GetComponent<Animator>(); if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)animator.runtimeAnimatorController)) { animator = null; return; } AnimatorControllerParameter[] parameters = animator.parameters; foreach (AnimatorControllerParameter val in parameters) { hasGrounded |= val.nameHash == IsGrounded; hasPitch |= val.nameHash == AimPitchCycle; hasYaw |= val.nameHash == AimYawCycle; } } if (hasGrounded) { animator.SetBool(IsGrounded, true); } if (hasPitch) { animator.SetFloat(AimPitchCycle, 0.5f); } if (hasYaw) { animator.SetFloat(AimYawCycle, 0.5f); } } } internal static class Flock { public const int Count = 3; public const float Lifetime = 20f; private const float Scale = 0.6f; private const string VanillaParamsKey = "RoR2/Base/Vulture/skinVultureBodyDefault_params.asset"; public static GameObject BodyPrefab; public static GameObject MasterPrefab; public static GameObject SpawnEffect; public static string SpawnSound; public static BodyIndex BodyIndex = (BodyIndex)(-1); private static readonly Dictionary<SkinThemes.Theme, SkinDef> ThemeSkins = new Dictionary<SkinThemes.Theme, SkinDef>(); public static void Create() { GameObject val = Asset.Load<GameObject>("RoR2/Base/Vulture/VultureBody.prefab"); GameObject val2 = Asset.Load<GameObject>("RoR2/Base/Vulture/VultureMaster.prefab"); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { SpawnEffect = Asset.Load<GameObject>("RoR2/Base/Vulture/VultureJumpEffect.prefab"); SpawnSound = Asset.EscString("RoR2/Base/Vulture/EntityStates.Vulture.SpawnState.asset", "spawnSoundString", "Play_vulture_spawn"); CreateBody(val); CreateSkins(val); CreateMaster(val2); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) BodyIndex = BodyCatalog.FindBodyIndex(BodyPrefab); }); } } private static void CreateBody(GameObject vanillaBody) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) BodyPrefab = PrefabAPI.InstantiateClone(vanillaBody, "NotHereticFledglingBody", true); Shrink(0.6f); CharacterBody component = BodyPrefab.GetComponent<CharacterBody>(); component.baseNameToken = "NOTHERETIC_FLEDGLING_NAME"; component.subtitleNameToken = ""; Object.DestroyImmediate((Object)(object)BodyPrefab.GetComponent<DeathRewards>()); EntityStateMachine[] components = BodyPrefab.GetComponents<EntityStateMachine>(); foreach (EntityStateMachine val in components) { if (val.customName == "Flight") { val.initialStateType = new SerializableEntityStateType(typeof(Fly)); } } ContentAddition.AddBody(BodyPrefab); } private static void Shrink(float scale) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_005f: 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) foreach (Transform item in BodyPrefab.transform) { item.localPosition *= scale; } Transform modelTransform = BodyPrefab.GetComponent<ModelLocator>().modelTransform; modelTransform.localScale *= scale; CapsuleCollider component = BodyPrefab.GetComponent<CapsuleCollider>(); BodyPrefab.GetComponent<KinematicCharacterMotor>().SetCapsuleDimensions(component.radius * scale, component.height * scale, component.center.y * scale); } private static void CreateSkins(GameObject vanillaBody) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)BodyPrefab.GetComponent<ModelLocator>().modelTransform).gameObject; SkinDefParams val = Asset.Load<SkinDefParams>("RoR2/Base/Vulture/skinVultureBodyDefault_params.asset"); if (!Object.op_Implicit((Object)(object)val)) { return; } Dictionary<string, Renderer> dictionary = new Dictionary<string, Renderer>(); Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { dictionary[((Object)val2).name] = val2; } List<MeshReplacement> list = new List<MeshReplacement>(); MeshReplacement[] meshReplacements = val.meshReplacements; foreach (MeshReplacement val3 in meshReplacements) { if (!Object.op_Implicit((Object)(object)val3.renderer) || !dictionary.TryGetValue(((Object)val3.renderer).name, out var value)) { continue; } Mesh val4 = (Object.op_Implicit((Object)(object)val3.mesh) ? val3.mesh : Asset.Load<Mesh>(val3.meshAddress)); if (Object.op_Implicit((Object)(object)val4)) { SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((value is SkinnedMeshRenderer) ? value : null); if (val5 != null) { val5.sharedMesh = val4; } else if (Object.op_Implicit((Object)(object)((Component)value).GetComponent<MeshFilter>())) { ((Component)value).GetComponent<MeshFilter>().sharedMesh = val4; } list.Add(new MeshReplacement { renderer = value, mesh = val4 }); } } List<RendererInfo> list2 = new List<RendererInfo>(); RendererInfo[] rendererInfos = val.rendererInfos; foreach (RendererInfo val6 in rendererInfos) { if (Object.op_Implicit((Object)(object)val6.renderer) && dictionary.TryGetValue(((Object)val6.renderer).name, out var value2)) { RendererInfo val7 = val6; val7.renderer = value2; if (!Object.op_Implicit((Object)(object)val7.defaultMaterial)) { val7.defaultMaterial = Asset.Load<Material>(val6.defaultMaterialAddress); } val7.defaultMaterialAddress = null; if (Object.op_Implicit((Object)(object)val7.defaultMaterial)) { list2.Add(val7); } } } if (list2.Count == 0) { foreach (Renderer value4 in dictionary.Values) { if (Object.op_Implicit((Object)(object)value4.sharedMaterial) && !(value4 is ParticleSystemRenderer)) { list2.Add(new RendererInfo { renderer = value4, defaultMaterial = value4.sharedMaterial, defaultShadowCastingMode = (ShadowCastingMode)1 }); } } } NotHereticPlugin.Log.LogDebug((object)($"Fledgling model: {dictionary.Count} renderers, vanilla skin has {val.rendererInfos.Length} materials " + string.Format("and {0} meshes; using {1} materials ({2}).", val.meshReplacements.Length, list2.Count, string.Join(", ", list2.ConvertAll((RendererInfo val10) => ((Object)val10.renderer).name + "=" + ((Object)val10.defaultMaterial).name))))); CharacterModel component = gameObject.GetComponent<CharacterModel>(); component.baseRendererInfos = list2.ToArray(); List<SkinDef> list3 = new List<SkinDef> { Skin("Default", "DEFAULT_SKIN", gameObject, component.baseRendererInfos, list.ToArray(), Array.Empty<ProjectileGhostReplacement>()) }; SkinThemes.Theme[] all = SkinThemes.All; foreach (SkinThemes.Theme theme in all) { try { Dictionary<Material, Material> dictionary2 = new Dictionary<Material, Material>(); RendererInfo[] array = component.baseRendererInfos.Clone() as RendererInfo[]; for (int num = 0; num < array.Length; num++) { Material defaultMaterial = array[num].defaultMaterial; if (Object.op_Implicit((Object)(object)defaultMaterial)) { if (!dictionary2.TryGetValue(defaultMaterial, out var value3)) { value3 = (dictionary2[defaultMaterial] = SkinThemes.Recolor(defaultMaterial, theme, PartOf(defaultMaterial), "NotHereticFledgling")); } array[num].defaultMaterial = value3; } } SkinDef val9 = Skin(theme.Name, "NOTHERETIC_SKIN_" + theme.Id + "_NAME", gameObject, array, list.ToArray(), Windblade.GhostReplacements(Windblade.VanillaProjectile, theme)); ThemeSkins[theme] = val9; list3.Add(val9); } catch (Exception arg) { NotHereticPlugin.Log.LogError((object)$"Could not build the {theme.Id} Fledgling skin: {arg}"); } } gameObject.GetComponent<ModelSkinController>().skins = list3.ToArray(); } private static SkinThemes.Part PartOf(Material material) { string name = ((Object)material).name; if (name.IndexOf("Eye", StringComparison.OrdinalIgnoreCase) < 0) { if (name.IndexOf("Feather", StringComparison.OrdinalIgnoreCase) < 0) { return SkinThemes.Part.Body; } return SkinThemes.Part.Feathers; } return SkinThemes.Part.Eye; } private static SkinDef Skin(string id, string nameToken, GameObject model, RendererInfo[] infos, MeshReplacement[] meshes, ProjectileGhostReplacement[] ghosts) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) return Skins.CreateNewSkinDef(new SkinDefParamsInfo { Name = "skinNotHereticFledgling" + id, NameToken = nameToken, Icon = Skins.CreateSkinIcon(Color.gray, Color.white, Color.black, Color.gray), RootObject = model, RendererInfos = infos, BaseSkins = Array.Empty<SkinDef>(), MeshReplacements = meshes, GameObjectActivations = Array.Empty<GameObjectActivation>(), ProjectileGhostReplacements = ghosts, MinionSkinReplacements = Array.Empty<MinionSkinReplacement>() }); } public static MinionSkinReplacement[] MinionSkinReplacements(SkinThemes.Theme theme) { //IL_002b: 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_0046: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)BodyPrefab) || !ThemeSkins.TryGetValue(theme, out var value)) { return Array.Empty<MinionSkinReplacement>(); } return (MinionSkinReplacement[])(object)new MinionSkinReplacement[1] { new MinionSkinReplacement { minionBodyPrefab = BodyPrefab, minionSkin = value } }; } private static void CreateMaster(GameObject vanillaMaster) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) MasterPrefab = PrefabAPI.InstantiateClone(vanillaMaster, "NotHereticFledglingMaster", true); MasterPrefab.GetComponent<CharacterMaster>().bodyPrefab = BodyPrefab; AISkillDriver val = null; AISkillDriver[] components = MasterPrefab.GetComponents<AISkillDriver>(); foreach (AISkillDriver val2 in components) { if ((int)val2.skillSlot == 0) { val = val2; } } float maxDistance = (Object.op_Implicit((Object)(object)val) ? val.maxDistance : 50f); components = MasterPrefab.GetComponents<AISkillDriver>(); for (int i = 0; i < components.Length; i++) { Object.DestroyImmediate((Object)(object)components[i]); } Driver("ReturnToLeader", (SkillSlot)(-1), (TargetType)2, 30f, float.PositiveInfinity, (MovementType)1, (AimType)4, requireLoS: false, sprint: true, resetEnemy: true); Driver("ShootWindblade", (SkillSlot)0, (TargetType)0, 0f, maxDistance, (MovementType)2, (AimType)2, requireLoS: true); Driver("ChaseEnemy", (SkillSlot)(-1), (TargetType)0, 0f, 70f, (MovementType)1, (AimType)1); Driver("FollowLeader", (SkillSlot)(-1), (TargetType)2, 7f, float.PositiveInfinity, (MovementType)1, (AimType)4); Driver("Idle", (SkillSlot)(-1), (TargetType)2, 0f, float.PositiveInfinity, (MovementType)0, (AimType)4); ContentAddition.AddMaster(MasterPrefab); } private static void Driver(string name, SkillSlot slot, TargetType target, float minDistance, float maxDistance, MovementType movement, AimType aim, bool requireLoS = false, bool sprint = false, bool resetEnemy = false) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001b: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) AISkillDriver obj = MasterPrefab.AddComponent<AISkillDriver>(); obj.customName = name; obj.skillSlot = slot; obj.requireSkillReady = (int)slot != -1; obj.moveTargetType = target; obj.minDistance = minDistance; obj.maxDistance = maxDistance; obj.movementType = movement; obj.aimType = aim; obj.selectionRequiresTargetLoS = requireLoS; obj.activationRequiresTargetLoS = requireLoS; obj.shouldSprint = sprint; obj.ignoreNodeGraph = true; obj.resetCurrentEnemyOnNextDriverSelection = resetEnemy; obj.buttonPressType = (ButtonPressType)0; obj.driverUpdateTimerOverride = -1f; } public static void Summon(CharacterBody owner) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)MasterPrefab) || !Object.op_Implicit((Object)(object)owner)) { return; } float num = Random.Range(0f, 360f); for (int i = 0; i < 3; i++) { Vector3 val = Quaternion.Euler(0f, num + (float)i * 120f, 0f) * Vector3.forward * 3f; Vector3 val2 = owner.corePosition + val + Vector3.up * 2f; CharacterMaster val3 = new MasterSummon { masterPrefab = MasterPrefab, position = val2, rotation = Util.QuaternionSafeLookRotation(val), summonerBodyObject = ((Component)owner).gameObject, ignoreTeamMemberLimit = true, inventoryToCopy = owner.inventory }.Perform(); if (Object.op_Implicit((Object)(object)val3)) { val3.inventory.GiveItemPermanent(Items.MinionLeash, 1); ((Component)val3).gameObject.AddComponent<MasterSuicideOnTimer>().lifeTimer = 20f; FlockTracker.Track(owner, val3); if (Object.op_Implicit((Object)(object)SpawnEffect)) { EffectManager.SpawnEffect(SpawnEffect, new EffectData { origin = val2, scale = 1f }, true); } } } } } public class FlockTracker : MonoBehaviour { private readonly List<CharacterMaster> fledglings = new List<CharacterMaster>(); public static void Track(CharacterBody owner, CharacterMaster fledgling) { if (Object.op_Implicit((Object)(object)owner.master)) { FlockTracker flockTracker = ((Component)owner.master).GetComponent<FlockTracker>(); if (!Object.op_Implicit((Object)(object)flockTracker)) { flockTracker = ((Component)owner.master).gameObject.AddComponent<FlockTracker>(); } flockTracker.fledglings.RemoveAll((CharacterMaster m) => !Object.op_Implicit((Object)(object)m) || !Object.op_Implicit((Object)(object)m.GetBody())); flockTracker.fledglings.Add(fledgling); while (flockTracker.fledglings.Count > 3) { flockTracker.fledglings[0].TrueKill(); flockTracker.fledglings.RemoveAt(0); } } } public static int Alive(CharacterMaster owner) { FlockTracker flockTracker = (Object.op_Implicit((Object)(object)owner) ? ((Component)owner).GetComponent<FlockTracker>() : null); if (!Object.op_Implicit((Object)(object)flockTracker)) { return 0; } flockTracker.fledglings.RemoveAll((CharacterMaster m) => !Object.op_Implicit((Object)(object)m) || !Object.op_Implicit((Object)(object)m.GetBody())); return flockTracker.fledglings.Count; } } internal static class HereticAssets { private const float HeresyHue = 0.77f; public static GameObject GaleEffect; public static GameObject UpdraftEffect; public static string GaleSound; public static string UpdraftSound; public static Sprite WindbladesIcon; public static Sprite GaleIcon; public static Sprite UpdraftIcon; public static Sprite FlockIcon; public static void Load() { GaleEffect = Asset.Load<GameObject>("RoR2/Base/LunarSkillReplacements/OmniExplosionCrowstorm.prefab"); UpdraftEffect = Asset.Load<GameObject>("RoR2/Base/Vulture/VultureJumpEffect.prefab"); GaleSound = Asset.EscString("RoR2/Base/Heretic/EntityStates.Heretic.Weapon.Squawk.asset", "soundName", "Play_heretic_squawk"); UpdraftSound = Asset.EscString("RoR2/Base/Vulture/EntityStates.Vulture.Fly.asset", "enterSoundString", "Play_vulture_attack1_shoot"); WindbladesIcon = Asset.Icon("RoR2/Base/Feather/texFeatherIcon.png", 0.77f); GaleIcon = Asset.Icon("RoR2/Base/JumpBoost/texWaxBirdIcon.png", 0.77f); UpdraftIcon = Asset.Icon("RoR2/Base/Jetpack/texChrysalisIcon.png", 0.77f); FlockIcon = Asset.Icon("RoR2/Base/Vulture/VultureBody.png", 0.77f); } } internal static class HereticSkills { public static SkillDef Windblades; public static SkillDef Gale; public static SkillDef Updraft; public static SkillDef CallOfTheFlock; public static void Create(GameObject body) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001a: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); ContentAddition.AddEntityState<FireWindblades>(ref flag); ContentAddition.AddEntityState<Gale>(ref flag); ContentAddition.AddEntityState<Updraft>(ref flag); ContentAddition.AddEntityState<CallFlock>(ref flag); Windblades = Skill("Windblades", typeof(FireWindblades), "Weapon", 0f, (InterruptPriority)0, HereticAssets.WindbladesIcon); Gale = Skill("Gale", typeof(Gale), "Weapon", 6f, (InterruptPriority)1, HereticAssets.GaleIcon, "KEYWORD_STUNNING"); Gale.mustKeyPress = true; Updraft = Skill("Updraft", typeof(Updraft), "Body", 6f, (InterruptPriority)2, HereticAssets.UpdraftIcon); Updraft.mustKeyPress = true; Updraft.cancelSprintingOnActivation = false; Updraft.isCombatSkill = false; CallOfTheFlock = Skill("CallOfTheFlock", typeof(CallFlock), "Weapon", 20f, (InterruptPriority)1, HereticAssets.FlockIcon); CallOfTheFlock.mustKeyPress = true; SkillLocator component = body.GetComponent<SkillLocator>(); AddVariant(component.primary, Windblades); AddVariant(component.secondary, Gale); AddVariant(component.utility, Updraft); AddVariant(component.special, CallOfTheFlock); } private static SkillDef Skill(string id, Type state, string machine, float cooldown, InterruptPriority priority, Sprite icon, params string[] keywords) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) SkillDef val = ScriptableObject.CreateInstance<SkillDef>(); val.skillName = "NotHeretic" + id; ((Object)val).name = val.skillName; string text = "NOTHERETIC_" + id.ToUpperInvariant(); val.skillNameToken = text + "_NAME"; val.skillDescriptionToken = text + "_DESCRIPTION"; val.keywordTokens = keywords; val.icon = icon; val.activationStateMachineName = machine; val.activationState = new SerializableEntityStateType(state); val.interruptPriority = priority; val.baseRechargeInterval = cooldown; val.baseMaxStock = 1; val.rechargeStock = 1; val.requiredStock = 1; val.stockToConsume = 1; val.fullRestockOnAssign = true; val.cancelSprintingOnActivation = true; val.canceledFromSprinting = false; val.beginSkillCooldownOnSkillEnd = false; val.isCombatSkill = true; val.mustKeyPress = false; ContentAddition.AddSkillDef(val); return val; } private static void AddVariant(GenericSkill slot, SkillDef skill) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = (Object.op_Implicit((Object)(object)slot) ? slot.skillFamily : null); if (!Object.op_Implicit((Object)(object)val)) { NotHereticPlugin.Log.LogError((object)("No skill slot for " + skill.skillName + ".")); return; } Variant[] array = val.variants; Array.Resize(ref array, array.Length + 1); Variant[] array2 = array; int num = array.Length - 1; Variant val2 = new Variant { skillDef = skill }; ((Variant)(ref val2)).viewableNode = new Node(skill.skillNameToken, false, (Node)null); array2[num] = val2; val.variants = array; } } internal static class HereticSkins { private const string ClothesMaterial = "matHereticClothes"; private const string FeatherMaterial = "matHereticFeathers"; private const string EyeMaterial = "matHereticEye"; public static void Create(GameObject model) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) CharacterModel component = model.GetComponent<CharacterModel>(); ModelSkinController component2 = model.GetComponent<ModelSkinController>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2)) { NotHereticPlugin.Log.LogError((object)"The Heretic model has no CharacterModel or ModelSkinController, skins are skipped."); return; } RendererInfo[] baseRendererInfos = component.baseRendererInfos; List<SkinDef> list = new List<SkinDef> { Skin("Default", "DEFAULT_SKIN", model, baseRendererInfos, SkinThemes.Icons(2038323, 8841727, 986394, 13281023), Array.Empty<ProjectileGhostReplacement>(), Array.Empty<MinionSkinReplacement>()) }; SkinThemes.Theme[] all = SkinThemes.All; foreach (SkinThemes.Theme theme in all) { try { Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>(); RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[baseRendererInfos.Length]; for (int j = 0; j < baseRendererInfos.Length; j++) { array[j] = baseRendererInfos[j]; Material defaultMaterial = baseRendererInfos[j].defaultMaterial; if (Object.op_Implicit((Object)(object)defaultMaterial)) { if (!dictionary.TryGetValue(defaultMaterial, out var value)) { value = (dictionary[defaultMaterial] = SkinThemes.Recolor(defaultMaterial, theme, PartOf(defaultMaterial), "NotHeretic")); } array[j].defaultMaterial = value; } } list.Add(Skin(theme.Name, "NOTHERETIC_SKIN_" + theme.Id + "_NAME", model, array, theme.Icon, Windblade.GhostReplacements(Windblade.Projectile, theme), Flock.MinionSkinReplacements(theme))); } catch (Exception arg) { NotHereticPlugin.Log.LogError((object)$"Could not build the {theme.Id} skin: {arg}"); } } component2.skins = list.ToArray(); } private static SkinThemes.Part PartOf(Material material) { string name = ((Object)material).name; if (!name.StartsWith("matHereticEye")) { if (!name.StartsWith("matHereticClothes")) { if (!name.StartsWith("matHereticFeathers")) { return SkinThemes.Part.Body; } return SkinThemes.Part.Feathers; } return SkinThemes.Part.Clothes; } return SkinThemes.Part.Eye; } private static SkinDef Skin(string id, string nameToken, GameObject model, RendererInfo[] infos, Color[] icon, ProjectileGhostReplacement[] ghosts, MinionSkinReplacement[] minions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) return Skins.CreateNewSkinDef(new SkinDefParamsInfo { Name = "skinNotHeretic" + id, NameToken = nameToken, Icon = Skins.CreateSkinIcon(icon[0], icon[1], icon[2], icon[3]), RootObject = model, RendererInfos = infos, BaseSkins = Array.Empty<SkinDef>(), MeshReplacements = Array.Empty<MeshReplacement>(), GameObjectActivations = Array.Empty<GameObjectActivation>(), ProjectileGhostReplacements = ghosts, MinionSkinReplacements = minions }); } } internal static class HereticSurvivor { private const string SurvivorKey = "RoR2/Base/Heretic/Heretic.asset"; private const string BodyKey = "RoR2/Base/Heretic/HereticBody.prefab"; private const float DisplayScale = 0.65f; private const string PrimarySkill = "LunarPrimaryReplacement"; private const string SecondarySkill = "LunarSecondaryReplacement"; private const string UtilitySkill = "LunarUtilityReplacement"; private const string SpecialSkill = "LunarDetonatorSpecialReplacement"; private static readonly FieldInfo SkillFamilyField = typeof(GenericSkill).GetField("_skillFamily", BindingFlags.Instance | BindingFlags.NonPublic); public static GameObject BodyPrefab; public static GameObject DisplayPrefab; public static SurvivorDef Survivor; public static BodyIndex BodyIndex = (BodyIndex)(-1); public static bool Load() { Survivor = Asset.Load<SurvivorDef>("RoR2/Base/Heretic/Heretic.asset"); BodyPrefab = Asset.Load<GameObject>("RoR2/Base/Heretic/HereticBody.prefab"); if (!Object.op_Implicit((Object)(object)Survivor) || !Object.op_Implicit((Object)(object)BodyPrefab)) { NotHereticPlugin.Log.LogError((object)"Heretic assets not found, the mod does nothing."); return false; } return true; } public static void Build() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) SetRegen(); OrderSkillSlots(); bool flag = default(bool); ContentAddition.AddEntityState<SpawnOnNewStageState>(ref flag); GameObject gameObject = ((Component)BodyPrefab.GetComponent<ModelLocator>().modelTransform).gameObject; HereticSkins.Create(gameObject); CreateDisplay(gameObject); Survivor.hidden = false; Survivor.displayPrefab = DisplayPrefab; Survivor.descriptionToken = "NOTHERETIC_DESCRIPTION"; RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnLoad)); CharacterBody.onBodyStartGlobal += RebuildRuinPassive; } private static void RebuildRuinPassive(CharacterBody body) { //IL_0008: 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) if (!NetworkServer.active || body.bodyIndex != BodyIndex || !Object.op_Implicit((Object)(object)body.skillLocator)) { return; } GenericSkill special = body.skillLocator.special; BaseSkillInstanceData val = ((Object.op_Implicit((Object)(object)special) && special.skillDef is LunarDetonatorSkill) ? special.skillInstanceData : null); if (val != null) { PropertyInfo property = ((object)val).GetType().GetProperty("skillSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || !property.CanWrite) { NotHereticPlugin.Log.LogWarning((object)"Ruin's passive could not be rebuilt; hits may not add Ruin."); return; } property.SetValue(val, null); property.SetValue(val, special); } } private static void SetRegen() { CharacterBody component = BodyPrefab.GetComponent<CharacterBody>(); component.baseRegen = NotHereticPlugin.HealthRegen.Value; component.levelRegen = component.baseRegen * 0.2f; } private static void OrderSkillSlots() { SkillLocator component = BodyPrefab.GetComponent<SkillLocator>(); GenericSkill[] components = BodyPrefab.GetComponents<GenericSkill>(); if (components.Length != 0 && !((Object)(object)components[^1] == (Object)(object)component.special) && Object.op_Implicit((Object)(object)component.special)) { GenericSkill special = component.special; SkillFamily skillFamily = special.skillFamily; string skillName = special.skillName; bool hideInCharacterSelect = special.hideInCharacterSelect; Object.DestroyImmediate((Object)(object)special); GenericSkill val = BodyPrefab.AddComponent<GenericSkill>(); val.skillName = skillName; val.hideInCharacterSelect = hideInCharacterSelect; SkillFamilyField.SetValue(val, skillFamily); component.special = val; } } private static void CreateDisplay(GameObject model) { //IL_001b: 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_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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) DisplayPrefab = PrefabAPI.InstantiateClone(model, "NotHereticDisplay", false); DisplayPrefab.transform.localPosition = Vector3.zero; DisplayPrefab.transform.localRotation = Quaternion.Inverse(BodyPrefab.transform.rotation) * model.transform.rotation; DisplayPrefab.transform.localScale = Vector3.one * 0.65f; Object.DestroyImmediate((Object)(object)DisplayPrefab.GetComponent<HurtBoxGroup>()); HurtBox[] componentsInChildren = DisplayPrefab.GetComponentsInChildren<HurtBox>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)((Component)componentsInChildren[i]).gameObject); } AimAssistTarget[] componentsInChildren2 = DisplayPrefab.GetComponentsInChildren<AimAssistTarget>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)((Component)componentsInChildren2[i]).gameObject); } Object.DestroyImmediate((Object)(object)DisplayPrefab.GetComponent<AimAnimator>()); Object.DestroyImmediate((Object)(object)DisplayPrefab.GetComponent<FootstepHandler>()); Object.DestroyImmediate((Object)(object)DisplayPrefab.GetComponent<RagdollController>()); DisplayPrefab.GetComponent<CharacterModel>().body = null; DisplayPrefab.AddComponent<DisplayPose>(); } private static void OnLoad() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) BodyIndex = BodyCatalog.FindBodyIndex(BodyPrefab); SkillLocator component = BodyPrefab.GetComponent<SkillLocator>(); SetSkill(component.primary, "LunarPrimaryReplacement"); SetSkill(component.secondary, "LunarSecondaryReplacement"); SetSkill(component.utility, "LunarUtilityReplacement"); SetSkill(component.special, "LunarDetonatorSpecialReplacement"); } private static void SetSkill(GenericSkill slot, string skillName) { SkillDef skillDef = SkillCatalog.GetSkillDef(SkillCatalog.FindSkillIndexByName(skillName)); if (!Object.op_Implicit((Object)(object)slot) || !Object.op_Implicit((Object)(object)slot.skillFamily) || !Object.op_Implicit((Object)(object)skillDef)) { NotHereticPlugin.Log.LogError((object)("Could not put " + skillName + " into the Heretic's skill slot.")); return; } slot.skillFamily.variants[0].skillDef = skillDef; slot.skillFamily.defaultVariantIndex = 0u; } } internal static class InnateHeresy { private const float RootDuration = 3f; private static readonly List<Hook> Hooks = new List<Hook>(); private static FieldInfo ghostDurationField; public static void Hook() { ghostDurationField = typeof(GhostUtilitySkillState).GetField("duration", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Add(typeof(LunarPrimaryReplacementSkill), "GetMaxStock", "PrimaryMaxStock"); Add(typeof(LunarPrimaryReplacementSkill), "GetRechargeInterval", "PrimaryRechargeInterval"); Add(typeof(LunarSecondaryReplacementSkill), "GetRechargeInterval", "SecondaryRechargeInterval"); Add(typeof(LunarDetonatorSkill), "GetRechargeInterval", "SpecialRechargeInterval"); Add(typeof(GhostUtilitySkillState), "OnEnter", "GhostOnEnter"); Add(typeof(GlobalEventManager), "ProcessHitEnemy", "ProcessHitEnemy"); } private static void Add(Type type, string method, string hookName) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown MethodInfo method2 = type.GetMethod(method, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method3 = typeof(InnateHeresy).GetMethod(hookName, BindingFlags.Static | BindingFlags.NonPublic); if (method2 == null) { NotHereticPlugin.Log.LogError((object)(type.Name + "." + method + " not found; that Heresy skill may not work without its item.")); } else { Hooks.Add(new Hook((MethodBase)method2, method3)); } } private static bool UsesInnateCopy(CharacterBody body, ItemDef item) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //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) if (!Object.op_Implicit((Object)(object)body) || (int)body.bodyIndex == -1 || body.bodyIndex != HereticSurvivor.BodyIndex) { return false; } if (Object.op_Implicit((Object)(object)body.inventory)) { return body.inventory.GetItemCountEffective(item) <= 0; } return true; } private static CharacterBody BodyOf(GenericSkill skillSlot) { if (!Object.op_Implicit((Object)(object)skillSlot)) { return null; } return skillSlot.characterBody; } private static int PrimaryMaxStock(Func<LunarPrimaryReplacementSkill, GenericSkill, int> orig, LunarPrimaryReplacementSkill self, GenericSkill skillSlot) { if (!UsesInnateCopy(BodyOf(skillSlot), Items.LunarPrimaryReplacement)) { return orig(self, skillSlot); } return ((SkillDef)self).baseMaxStock; } private static float PrimaryRechargeInterval(Func<LunarPrimaryReplacementSkill, GenericSkill, float> orig, LunarPrimaryReplacementSkill self, GenericSkill skillSlot) { if (!UsesInnateCopy(BodyOf(skillSlot), Items.LunarPrimaryReplacement)) { return orig(self, skillSlot); } return ((SkillDef)self).baseRechargeInterval; } private static float SecondaryRechargeInterval(Func<LunarSecondaryReplacementSkill, GenericSkill, float> orig, LunarSecondaryReplacementSkill self, GenericSkill skillSlot) { if (!UsesInnateCopy(BodyOf(skillSlot), Items.LunarSecondaryReplacement)) { return orig(self, skillSlot); } return ((SkillDef)self).baseRechargeInterval; } private static float SpecialRechargeInterval(Func<LunarDetonatorSkill, GenericSkill, float> orig, LunarDetonatorSkill self, GenericSkill skillSlot) { if (!UsesInnateCopy(BodyOf(skillSlot), Items.LunarSpecialReplacement)) { return orig(self, skillSlot); } return ((SkillDef)self).baseRechargeInterval; } private static void GhostOnEnter(Action<GhostUtilitySkillState> orig, GhostUtilitySkillState self) { orig(self); CharacterBody body = (Object.op_Implicit((Object)(object)((EntityState)self).outer) ? ((EntityState)self).outer.commonComponents.characterBody : null); if (ghostDurationField != null && UsesInnateCopy(body, Items.LunarUtilityReplacement)) { ghostDurationField.SetValue(self, GhostUtilitySkillState.baseDuration); } } private static void ProcessHitEnemy(Action<GlobalEventManager, DamageInfo, GameObject> orig, GlobalEventManager self, DamageInfo damageInfo, GameObject victim) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) orig(self, damageInfo, victim); if (!NetworkServer.active || damageInfo == null || damageInfo.rejected || damageInfo.procCoefficient <= 0f || !Object.op_Implicit((Object)(object)victim) || !Object.op_Implicit((Object)(object)damageInfo.attacker) || (DamageTypeCombo.op_Implicit(damageInfo.damageType) & 0x2000000) == 0) { return; } CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.master) && UsesInnateCopy(component, Items.LunarSecondaryReplacement)) { CharacterBody component2 = victim.GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component2) && !component2.HasBuff(Buffs.HiddenRejectAllDamage) && (!Object.op_Implicit((Object)(object)component2.teamComponent) || !Object.op_Implicit((Object)(object)component.teamComponent) || component2.teamComponent.teamIndex != component.teamComponent.teamIndex)) { component2.AddTimedBuff(Buffs.LunarSecondaryRoot, 3f); } } } } [BepInPlugin("NotHeretic", "NotHeretic", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class NotHereticPlugin : BaseUnityPlugin { public const string PluginGUID = "NotHeretic"; public const string PluginName = "NotHeretic"; public const string PluginVersion = "1.1.1"; internal static ManualLogSource Log; internal static ConfigEntry<float> HealthRegen; private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; HealthRegen = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Health regen", 1f, new ConfigDescription("Health regenerated per second at level 1. Like in vanilla, it grows by 20% of this value every level. The vanilla Heretic has -6 (it keeps losing health), which only works for a character you turn into late in a run. Applies to every Heretic, also one you turn into with the Heresy items. In multiplayer the host's value counts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-10f, 10f), Array.Empty<object>())); Tokens.Register(); if (HereticSurvivor.Load()) { HereticAssets.Load(); Windblade.Create(); Flock.Create(); HereticSkills.Create(HereticSurvivor.BodyPrefab); HereticSurvivor.Build(); InnateHeresy.Hook(); } } } internal static class SkinThemes { public enum Part { Body, Clothes, Feathers, Eye } public sealed class Theme { public string Id; public Color[] Body; public Color[] Clothes; public Color[] Feathers; public float Contrast = 1.3f; public Color Glow; public float GlowPower = 2.5f; public string RimRamp; public float RimPower = 1.8f; public float RimBoost = 1.6f; public float Smoothness; public float Specular; public Color[] Icon; public string Name => Id.Substring(0, 1) + Id.Substring(1).ToLowerInvariant(); public Color Tint { get { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(Glow.r, Mathf.Max(Glow.g, Glow.b)); if (!(num > 0f)) { return Color.white; } return new Color(Glow.r / num, Glow.g / num, Glow.b / num, 1f); } } } public static readonly Theme[] All = new Theme[5] { new Theme { Id = "VOID", Body = Palette(328458, 1706035, 4527470, 9191641, 15583231), Clothes = Palette(327944, 1312031, 2820672, 5182576, 10110416), Feathers = Palette(196870, 1312299, 3805286, 10045414, 15915519), Glow = new Color(1.2f, 0.3f, 1.8f), RimRamp = "RoR2/DLC1/Common/ColorRamps/texRampVoidArenaShield.png", Icon = Icons(1706035, 10369279, 4002928, 16741375) }, new Theme { Id = "BLAZING", Body = Palette(524800, 3017218, 7543301, 14244109, 16767347), Clothes = Palette(459009, 2032899, 4525061, 8002056, 14243354), Feathers = Palette(655872, 4197634, 10034949, 15885844, 16770688), Glow = new Color(2f, 0.7f, 0.1f), RimRamp = "RoR2/Base/Common/ColorRamps/texRampMageFire.png", Icon = Icons(3017218, 16747546, 7543301, 16767347) }, new Theme { Id = "GLACIAL", Body = Palette(1713203, 5072512, 9221068, 13757434, 16777215), Clothes = Palette(330260, 990515, 2046556, 3827088, 10275051), Feathers = Palette(2504269, 6720691, 10931430, 14743039, 16777215), Contrast = 1.15f, Glow = new Color(0.5f, 1.3f, 2f), GlowPower = 2f, RimRamp = "RoR2/Base/Common/ColorRamps/texRampIce.png", Smoothness = 0.35f, Specular = 0.3f, Icon = Icons(5072512, 9230847, 2044754, 16777215) }, new Theme { Id = "GILDED", Body = Palette(1707778, 6044168, 11565586, 15777856, 16773296), Clothes = Palette(525571, 1970698, 4006928, 7029528, 13211450), Feathers = Palette(2036227, 7555594, 13210648, 16766287, 16775382), Glow = new Color(1.7f, 1.15f, 0.3f), GlowPower = 2f, RimRamp = "RoR2/DLC1/Common/ColorRamps/texRampGold.png", Smoothness = 0.6f, Specular = 0.6f, Icon = Icons(5058058, 16767309, 2036752, 16775116) }, new Theme { Id = "MALACHITE", Body = Palette(133125, 536090, 1336878, 4243302, 13107153), Clothes = Palette(66563, 332813, 732700, 1528634, 5223813), Feathers = Palette(199174, 868386, 1739840, 5888384, 14745574), Glow = new Color(0.3f, 1.8f, 0.6f), RimRamp = "RoR2/Base/Common/ColorRamps/texRampElitePoison.png", Icon = Icons(536090, 4259712, 331530, 13107153) } }; private static readonly Dictionary<Texture, Texture2D> GrayCache = new Dictionary<Texture, Texture2D>(); public static Texture Ramp(Theme theme) { if (!string.IsNullOrEmpty(theme.RimRamp)) { return Asset.Load<Texture>(theme.RimRamp); } return null; } public static Material Recolor(Material source, Theme theme, Part part, string owner) { //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_001f: Expected O, but got Unknown //IL_0030: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(source) { name = ((Object)source).name + owner + theme.Name }; Color[] array; switch (part) { case Part.Eye: val.SetColor("_Color", theme.Body[1]); val.SetColor("_EmColor", theme.Glow); val.SetFloat("_EmPower", 1.5f); SetRim(val, theme); return val; default: array = theme.Body; break; case Part.Feathers: array = theme.Feathers; break; case Part.Clothes: array = theme.Clothes; break; } Color[] palette = array; Texture val2 = (source.HasProperty("_MainTex") ? source.GetTexture("_MainTex") : null); if (Object.op_Implicit((Object)(object)val2)) { val.SetTexture("_MainTex", (Texture)(object)TextureTools.GradientMap(val2, palette, theme.Contrast, 0.35f, part == Part.Clothes)); } if (val.HasProperty("_Color")) { val.SetColor("_Color", Color.white); } Texture val3 = (source.HasProperty("_EmTex") ? source.GetTexture("_EmTex") : null); if (Object.op_Implicit((Object)(object)val3)) { if (!GrayCache.TryGetValue(val3, out var value)) { value = TextureTools.Grayscale(val3); GrayCache[val3] = value; } val.SetTexture("_EmTex", (Texture)(object)value); val.SetColor("_EmColor", theme.Glow); val.SetFloat("_EmPower", theme.GlowPower); } if (part == Part.Body || part == Part.Feathers) { SetRim(val, theme); } if (theme.Smoothness > 0f) { val.EnableKeyword("FORCE_SPEC"); val.SetFloat("_ForceSpecOn", 1f); val.SetFloat("_Smoothness", theme.Smoothness); val.SetFloat("_SpecularStrength", theme.Specular); val.SetFloat("_SpecularExponent", 6f); } return val; } private static void SetRim(Material mat, Theme theme) { Texture val = Ramp(theme); if (Object.op_Implicit((Object)(object)val) && mat.HasProperty("_FresnelRamp")) { mat.SetTexture("_FresnelRamp", val); mat.SetFloat("_FEON", 1f); mat.EnableKeyword("FRESNEL_EMISSION"); mat.SetFloat("_FresnelPower", theme.RimPower); mat.SetFloat("_FresnelBoost", theme.RimBoost); } } public static void RecolorEffect(GameObject root, Theme theme) { //IL_0008: 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_00aa: 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_00b3: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Invalid comparison between Unknown and I4 //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_00cd: 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_010d: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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) Texture ramp = Ramp(theme); Color tint = theme.Tint; Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>(); Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] sharedMaterials = val.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if (Object.op_Implicit((Object)(object)val2)) { if (!dictionary.TryGetValue(val2, out var value)) { value = (dictionary[val2] = RecolorEffectMaterial(val2, ramp, tint, theme.Name)); } sharedMaterials[j] = value; } } val.sharedMaterials = sharedMaterials; } ParticleSystem[] componentsInChildren2 = root.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { MainModule main = componentsInChildren2[i].main; MinMaxGradient startColor = ((MainModule)(ref main)).startColor; if ((int)((MinMaxGradient)(ref startColor)).mode == 0) { ((MinMaxGradient)(ref startColor)).color = Retint(((MinMaxGradient)(ref startColor)).color, tint); } else if ((int)((MinMaxGradient)(ref startColor)).mode == 2) { ((MinMaxGradient)(ref startColor)).colorMin = Retint(((MinMaxGradient)(ref startColor)).colorMin, tint); ((MinMaxGradient)(ref startColor)).colorMax = Retint(((MinMaxGradient)(ref startColor)).colorMax, tint); } ((MainModule)(ref main)).startColor = startColor; } TrailRenderer[] componentsInChildren3 = root.GetComponentsInChildren<TrailRenderer>(true); foreach (TrailRenderer obj in componentsInChildren3) { obj.startColor = Retint(obj.startColor, tint); obj.endColor = Retint(obj.endColor, tint); } Light[] componentsInChildren4 = root.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { componentsInChildren4[i].color = tint; } } private static Material RecolorEffectMaterial(Material material, Texture ramp, Color tint, string themeName) { //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) //IL_0037: Expected O, but got Unknown //IL_008c: 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_0092: Unknown result type (might be due to invalid IL or missing references) if (((Object)material.shader).name.Contains("Distortion")) { return material; } Material val = new Material(material) { name = ((Object)material).name + "NotHeretic" + themeName }; if (Object.op_Implicit((Object)(object)ramp) && val.HasProperty("_RemapTex")) { val.SetTexture("_RemapTex", ramp); } string[] array = new string[3] { "_TintColor", "_Color", "_EmColor" }; foreach (string text in array) { if (val.HasProperty(text)) { val.SetColor(text, Retint(val.GetColor(text), tint)); } } return val; } private static Color Retint(Color c, Color tint) { //IL_0008: 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_001a: 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) //IL_0037: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (Mathf.Max(new float[3] { c.r, c.g, c.b }) - Mathf.Min(new float[3] { c.r, c.g, c.b }) < 0.05f && Mathf.Max(new float[3] { c.r, c.g, c.b }) < 0.95f) { return c; } float num = Mathf.Max(new float[3] { c.r, c.g, c.b }); return new Color(tint.r * num, tint.g * num, tint.b * num, c.a); } private static Color[] Palette(params int[] hex) { //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) Color[] array = (Color[])(object)new Color[hex.Length]; for (int i = 0; i < hex.Length; i++) { array[i] = Hex(hex[i]); } return array; } public static Color[] Icons(int top, int right, int bottom, int left) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0028: 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_0035: Unknown result type (might be due to invalid IL or missing references) return (Color[])(object)new Color[4] { Hex(top), Hex(right), Hex(bottom), Hex(left) }; } private static Color Hex(int rgb) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) return new Color((float)((rgb >> 16) & 0xFF) / 255f, (float)((rgb >> 8) & 0xFF) / 255f, (float)(rgb & 0xFF) / 255f); } } internal static class TextureTools { public static Texture2D ReadableCopy(Texture source, bool mipChain) { //IL_0037: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); Graphics.Blit(source, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, mipChain, false); val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); return val; } public static Texture2D GradientMap(Texture source, Color[] palette, float contrast, float midpoint, bool byValue) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00bd: 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) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) Texture2D val = ReadableCopy(source, mipChain: true); Color32[] pixels = val.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val2 = pixels[i]; float num = (byValue ? ((float)Mathf.Max((int)val2.r, Mathf.Max((int)val2.g, (int)val2.b)) / 255f) : ((0.299f * (float)(int)val2.r + 0.587f * (float)(int)val2.g + 0.114f * (float)(int)val2.b) / 255f)); num = Mathf.Clamp01((num - midpoint) * contrast + midpoint); Color val3 = SamplePalette(palette, num); pixels[i] = new Color32((byte)(val3.r * 255f), (byte)(val3.g * 255f), (byte)(val3.b * 255f), val2.a); } val.SetPixels32(pixels); val.Apply(true, true); ((Texture)val).wrapMode = source.wrapMode; ((Texture)val).filterMode = source.filterMode; ((Texture)val).anisoLevel = source.anisoLevel; ((Object)val).name = ((Object)source).name + "NotHeretic"; return val; } public static Texture2D Grayscale(Texture source) { //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_001b: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = ReadableCopy(source, mipChain: true); Color32[] pixels = val.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val2 = pixels[i]; byte b = (byte)Mathf.Max((int)val2.r, Mathf.Max((int)val2.g, (int)val2.b)); pixels[i] = new Color32(b, b, b, val2.a); } val.SetPixels32(pixels); val.Apply(true, true); ((Texture)val).wrapMode = source.wrapMode; ((Object)val).name = ((Object)source).name + "NotHereticGray"; return val; } public static Texture2D HueShift(Texture source, float hue) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0051: Unknown result type (might be due to invalid IL or missing references) Texture2D val = ReadableCopy(source, mipChain: false); Color[] pixels = val.GetPixels(); float num = default(float); float num2 = default(float); float num3 = default(float); for (int i = 0; i < pixels.Length; i++) { Color.RGBToHSV(pixels[i], ref num, ref num2, ref num3); if (num2 > 0.08f) { Color val2 = Color.HSVToRGB(hue, num2, num3); val2.a = pixels[i].a; pixels[i] = val2; } } val.SetPixels(pixels); val.Apply(false, true); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).name = ((Object)source).name + "NotHeretic"; return val; } public static Color SamplePalette(Color[] palette, float t) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(t) * (float)(palette.Length - 1); int num2 = Mathf.Min((int)num, palette.Length - 2); return Color.Lerp(palette[num2], palette[num2 + 1], num - (float)num2); } } internal static class Tokens { public const string Prefix = "NOTHERETIC_"; public static void Register() { Add("DESCRIPTION", "The Heretic stole the four Heresies of the Moon and was cast out for it. Every skill is one of them, and every Heresy you find makes its skill stronger.<color=#CCD3E0>\n\n< ! > Hungering Gaze holds up to 12 shards that home in and burst after a short delay. Keep the pressure on while they reload.\n\n< ! > Slicing Maelstrom roots everything it hits. Throw it into a crowd before you commit.\n\n< ! > Shadowfade makes you intangible and heals you. Use it to escape or to cross open ground.\n\n< ! > Every hit adds Ruin to enemies. Ruin detonates all of it at once, from any distance.\n\n< ! > You count as holding one of each Heresy. Extra copies stack as usual.\n\n< ! > The Loadout tab has a second skill for every slot: windblades, a gale, an updraft and a flock of Fledglings.</color>\n"); Add("WINDBLADES_NAME", "Windblades"); Add("WINDBLADES_DESCRIPTION", $"Hurl a spread of <style=cIsDamage>{3}</style> windblades for " + $"<style=cIsDamage>{3}x{Percent(1.2f)} damage</style>."); Add("GALE_NAME", "Gale"); Add("GALE_DESCRIPTION", "<style=cIsDamage>Stunning</style>. Beat your wings to blast a burst of crows and wind in front of you for <style=cIsDamage>" + Percent(5f) + " damage</style>, <style=cIsUtility>throwing enemies back</style>."); Add("UPDRAFT_NAME", "Updraft"); Add("UPDRAFT_DESCRIPTION", "Launch yourself where you aim, <style=cIsUtility>invulnerable</style> for a moment, then <style=cIsUtility>glide</style> down slowly. You can keep attacking in the air."); Add("CALLOFTHEFLOCK_NAME", "Call of the Flock"); Add("CALLOFTHEFLOCK_DESCRIPTION", $"Call <style=cIsUtility>{3} Fledglings</style>, small Alloy Vultures that <style=cIsUtility>copy your items</style> " + $"and throw windblades at your enemies for <style=cIsUtility>{20f:0} seconds</style>. Calling again replaces them."); Add("FLEDGLING_NAME", "Fledgling"); Add("SKIN_VOID_NAME", "Void Heretic"); Add("SKIN_BLAZING_NAME", "Blazing Heretic"); Add("SKIN_GLACIAL_NAME", "Glacial Heretic"); Add("SKIN_GILDED_NAME", "Gilded Heretic"); Add("SKIN_MALACHITE_NAME", "Malachite Heretic"); } private static string Percent(float coefficient) { return (coefficient * 100f).ToString("0", CultureInfo.InvariantCulture) + "%"; } private static void Add(string key, string text) { LanguageAPI.Add("NOTHERETIC_" + key, text); } } internal static class Windblade { private const string ProjectileKey = "RoR2/Base/Vulture/WindbladeProjectile.prefab"; private const string GhostKey = "RoR2/Base/Vulture/WindbladeProjectileGhost.prefab"; private const float Speed = 90f; private const float Lifetime = 1.6f; public static GameObject Projectile; public static GameObject VanillaProjectile; public static GameObject MuzzleEffect; public static string Sound; private static GameObject vanillaGhost; private static readonly Dictionary<SkinThemes.Theme, GameObject> Ghosts = new Dictionary<SkinThemes.Theme, GameObject>(); public static void Create() { VanillaProjectile = Asset.Load<GameObject>("RoR2/Base/Vulture/WindbladeProjectile.prefab"); vanillaGhost = Asset.Load<GameObject>("RoR2/Base/Vulture/WindbladeProjectileGhost.prefab"); MuzzleEffect = Asset.EscObject<GameObject>("RoR2/Base/Vulture/EntityStates.Vulture.Weapon.FireWindblade.asset", "muzzleEffectPrefab"); Sound = Asset.EscString("RoR2/Base/Vulture/EntityStates.Vulture.Weapon.ChargeWindblade.asset", "soundString"); if (Object.op_Implicit((Object)(object)VanillaProjectile)) { Projectile = PrefabAPI.InstantiateClone(VanillaProjectile, "NotHereticWindbladeProjectile", true); ProjectileSimple component = Projectile.GetComponent<ProjectileSimple>(); if (Object.op_Implicit((Object)(object)component)) { component.desiredForwardSpeed = 90f; component.lifetime = 1.6f; } ContentAddition.AddProjectile(Projectile); } } public static GameObject Ghost(SkinThemes.Theme theme) { if (!Object.op_Implicit((Object)(object)vanillaGhost)) { return null; } if (!Ghosts.TryGetValue(theme, out var value)) { value = PrefabAPI.InstantiateClone(vanillaGhost, "NotHereticWindbladeGhost" + theme.Name, false); SkinThemes.RecolorEffect(value, theme); Ghosts[theme] = value; } return value; } public static ProjectileGhostReplacement[] GhostReplacements(GameObject projectile, SkinThemes.Theme theme) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) GameObject val = Ghost(theme); if (!Object.op_Implicit((Object)(object)projectile) || !Object.op_Implicit((Object)(object)val)) { return Array.Empty<ProjectileGhostReplacement>(); } return (ProjectileGhostReplacement[])(object)new ProjectileGhostReplacement[1] { new ProjectileGhostReplacement { projectilePrefab = projectile, projectileGhostReplacementPrefab = val } }; } } } namespace NotHeretic.States { internal static class Anim { public static bool Has(Animator animator, string layer, string state) { if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)animator.runtimeAnimatorController)) { return false; } int layerIndex = animator.GetLayerIndex(layer); if (layerIndex >= 0) { return animator.HasState(layerIndex, Animator.StringToHash(state)); } return false; } } public class CallFlock : BaseSkillState { public const float BaseDuration = 0.8f; private float duration; public override void OnEnter() { ((BaseState)this).OnEnter(); duration = 0.8f / ((BaseState)this).attackSpeedStat; if (Anim.Has(((EntityState)this).GetModelAnimator(), "FullBody, Override", "LunarSpecial")) { ((EntityState)this).PlayAnimation("FullBody, Override", "LunarSpecial", "LunarSpecial.playbackRate", duration, 0f); } Util.PlaySound(HereticAssets.GaleSound, ((EntityState)this).gameObject); Util.PlaySound(Flock.SpawnSound, ((EntityState)this).gameObject); if (NetworkServer.active) { Flock.Summon(((EntityState)this).characterBody); } } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= duration) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class FireWindblades : BaseSkillState { public const float BaseDuration = 0.6f; public const float DamageCoefficient = 1.2f; public const int Count = 3; private const float Spread = 6f; private const float Force = 300f; private float duration; public override void OnEnter() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_00be: 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) //IL_00c8: 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_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_00ef: 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_00f4: 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_0114: 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_0127: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_018c: 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) ((BaseState)this).OnEnter(); duration = 0.6f / ((BaseState)this).attackSpeedStat; Ray aimRay = ((BaseState)this).GetAimRay(); ((BaseState)this).StartAimMode(aimRay, 2f, false); if (Anim.Has(((EntityState)this).GetModelAnimator(), "Gesture, Override", "FireLunarNeedle")) { ((EntityState)this).PlayAnimation("Gesture, Override", "FireLunarNeedle", "FireLunarNeedle.playbackRate", duration, 0f); } Util.PlaySound(Windblade.Sound, ((EntityState)this).gameObject); if (Object.op_Implicit((Object)(object)Windblade.MuzzleEffect)) { EffectManager.SimpleMuzzleFlash(Windblade.MuzzleEffect, ((EntityState)this).gameObject, "Head", false); } if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)Windblade.Projectile)) { bool crit = ((BaseState)this).RollCrit(); Vector3 val = Vector3.Cross(Vector3.up, ((Ray)(ref aimRay)).direction); Vector3 val2; if (!(((Vector3)(ref val)).sqrMagnitude > 0.001f)) { val2 = Vector3.up; } else { Vector3 val3 = Vector3.Cross(((Ray)(ref aimRay)).direction, val); val2 = ((Vector3)(ref val3)).normalized; } Vector3 val4 = val2; for (int i = 0; i < 3; i++) { Vector3 val5 = Quaternion.AngleAxis(((float)i - 1f) * 6f, val4) * ((Ray)(ref aimRay)).direction; ProjectileManager.instance.FireProjectile(new FireProjectileInfo { projectilePrefab = Windblade.Projectile, position = ((Ray)(ref aimRay)).origin, rotation = Util.QuaternionSafeLookRotation(val5), owner = ((EntityState)this).gameObject, damage = ((BaseState)this).damageStat * 1.2f, force = 300f, crit = crit, damageTypeOverride = DamageTypeCombo.op_Implicit((DamageSource)1) }); } } ((EntityState)this).characterBody.AddSpreadBloom(0.4f); } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= duration) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class Gale : BaseSkillState { public const float BaseDuration = 0.5f; public const float DamageCoefficient = 5f; public const float Radius = 9f; private const float Reach = 6f; private const float PushForce = 3500f; private const float LiftForce = 800f; private const float Recoil = 8f; private float duration; public override void OnEnter() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_00ff: 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) //IL_0105: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0134: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0197: 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_00b2: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: 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_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) ((BaseState)this).OnEnter(); duration = 0.5f / ((BaseState)this).attackSpeedStat; Ray aimRay = ((BaseState)this).GetAimRay(); ((BaseState)this).StartAimMode(aimRay, 2f, false); if (Anim.Has(((EntityState)this).GetModelAnimator(), "Gesture, Override", "FireLunarSecondary")) { ((EntityState)this).PlayAnimation("Gesture, Override", "FireLunarSecondary", "FireLunarSecondary.playbackRate", duration, 0f); } Util.PlaySound(HereticAssets.GaleSound, ((EntityState)this).gameObject); if (((EntityState)this).isAuthority) { Vector3 direction = ((Ray)(ref aimRay)).direction; Vector3 val = ((EntityState)this).characterBody.corePosition + direction * 6f; if (Object.op_Implicit((Object)(object)HereticAssets.GaleEffect)) { EffectManager.SpawnEffect(HereticAssets.GaleEffect, new EffectData { origin = val, rotation = Util.QuaternionSafeLookRotation(direction), scale = 9f }, true); } new BlastAttack { attacker = ((EntityState)this).gameObject, inflictor = ((EntityState)this).gameObject, teamIndex = ((BaseState)this).GetTeam(), position = val, radius = 9f, baseDamage = ((BaseState)this).damageStat * 5f, baseForce = 0f, bonusForce = direction * 3500f + Vector3.up * 800f, crit = ((BaseState)this).RollCrit(), procCoefficient = 1f, falloffModel = (FalloffModel)0, damageType = (DamageTypeCombo.op_Implicit((DamageSource)2) | DamageTypeCombo.op_Implicit((DamageType)32)), attackerFiltering = (AttackerFiltering)2, damageColorIndex = (DamageColorIndex)0 }.Fire(); if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { Vector3 val2 = -direction; val2.y = 0f; CharacterMotor characterMotor = ((EntityState)this).characterMotor; characterMotor.velocity += ((Vector3)(ref val2)).normalized * 8f + Vector3.up * (((EntityState)this).characterMotor.isGrounded ? 0f : 4f); } } } public override void FixedUpdate() { ((EntityState)this).FixedUpdate(); if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge >= duration) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { return (InterruptPriority)1; } } public class Updraft : GenericCharacterMain { public const float LaunchSpeed = 36f; public const float InvulnerableTime = 0.5f; public const float MaxDuration = 3f; public const float GlideFallSpeed = 4f; private const float MinUpward = 0.45f; private const float LaunchTime = 0.35f; public override void OnEnter() { //IL_00ae: 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_00b6: 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_00be: 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_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_0086: 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_0092: 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_00ad: Expected O, but got Unknown ((GenericCharacterMain)this).OnEnter(); Util.PlaySound(HereticAssets.UpdraftSound, ((EntityState)this).gameObject); if (Anim.Has(((EntityState)this).GetModelAnimator(), "Body", "BonusJump")) { ((EntityState)this).PlayCrossfade("Body", "BonusJump", 0.1f); } if (NetworkServer.active) { ((EntityState)this).characterBody.AddTimedBuff(Buffs.HiddenInvincibility, 0.5f); } if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { if (Object.op_Implicit((Object)(object)HereticAssets.UpdraftEffect)) { EffectManager.SpawnEffect(HereticAssets.UpdraftEffect, new EffectData { origin = ((EntityState)this).characterBody.footPosition, scale = 2f }, true); } Ray aimRay = ((BaseState)this).GetAimRay(); Vector3 direction = ((Ray)(ref aimRay)).direction; direction.y = Mathf.Max(direction.y, 0.45f); ((Vector3)(ref direction)).Normalize(); ((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f); ((EntityState)this).characterMotor.velocity = direction * 36f; } } public override void FixedUpdate() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0055: Unknown result type (might be due to invalid IL or missing references) ((GenericCharacterMain)this).FixedUpdate(); if (!((EntityState)this).isAuthority || !Object.op_Implicit((Object)(object)((EntityState)this).characterMotor)) { return; } if (((EntityState)this).fixedAge > 0.35f) { Vector3 velocity = ((EntityState)this).characterMotor.velocity; if (velocity.y < -4f) { velocity.y = -4f; ((EntityState)this).characterMotor.velocity = velocity; } if (((EntityState)this).characterMotor.isGrounded) { ((EntityState)this).outer.SetNextStateToMain(); return; } } if (((EntityState)this).fixedAge >= 3f) { ((EntityState)this).outer.SetNextStateToMain(); } } public override InterruptPriority GetMinimumInterruptPriority() { if (((EntityState)this).fixedAge < 0.35f) { return (InterruptPriority)2; } return (InterruptPriority)0; } } }