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 ConcentricContent v1.0.2
plugins/ConcentricContent/ConcentricContent.dll
Decompiled a year agousing System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Logging; using EntityStates; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using RoR2; using RoR2.ContentManagement; using RoR2.Skills; using RoR2.UI; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("ConcentricContent")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ConcentricContent")] [assembly: AssemblyTitle("ConcentricContent")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace ConcentricContent { public abstract class Concentric { public static readonly Dictionary<string, object> Objects = new Dictionary<string, object>(); public static readonly Dictionary<Type, Concentric> Assets = new Dictionary<Type, Concentric>(); public static readonly Dictionary<object, Concentric> ObjectToAssetMap = new Dictionary<object, Concentric>(); public static readonly List<IOverlay> Overlays = new List<IOverlay>(); public static readonly List<IMaterialSwap> MaterialSwaps = new List<IMaterialSwap>(); public static readonly Dictionary<IMaterialSwap, Material> MaterialSwapMaterials = new Dictionary<IMaterialSwap, Material>(); public static readonly Dictionary<IOverlay, Material> OverlayMaterials = new Dictionary<IOverlay, Material>(); public static readonly ConcurrentDictionary<string, Task<object?>> Tasks = new ConcurrentDictionary<string, Task<object>>(Environment.ProcessorCount * 2, 64); public virtual bool Enabled => true; public static Task<ItemDef> GetItemDef<T>() where T : Concentric, IItem { return GetObjectOrThrow<T, IItem, ItemDef>(); } public static async Task<ItemIndex> GetItemIndex<T>() where T : Concentric, IItem { return (await GetObjectOrThrow<T, IItem, ItemDef>()).itemIndex; } public static Task<UnlockableDef> GetUnlockableDef<T>() where T : Concentric, IUnlockable { return GetObjectOrThrow<T, IUnlockable, UnlockableDef>(); } public static Task<BuffDef> GetBuffDef<T>() where T : Concentric, IBuff { return GetObjectOrThrow<T, IBuff, BuffDef>(); } public static async Task<BuffIndex> GetBuffIndex<T>() where T : Concentric, IBuff { return (await GetObjectOrThrow<T, IBuff, BuffDef>()).buffIndex; } public static async Task<BodyIndex> GetBodyIndex<T>() where T : Concentric, IBody { return (await GetObjectOrThrow<T, IBody, GameObject>()).GetComponent<CharacterBody>().bodyIndex; } public static Task<Material> GetMaterial<T>() where T : Concentric, IMaterial { return GetObjectOrThrow<T, IMaterial, Material>(); } public static Task<SurvivorDef> GetSurvivorDef<T>() where T : Concentric, ISurvivor { return GetObjectOrThrow<T, ISurvivor, SurvivorDef>(); } public static Task<SkinDef> GetSkinDef<T>() where T : Concentric, ISkin { return GetObjectOrThrow<T, ISkin, SkinDef>(); } public static Task<SkillDef> GetSkillDef<T>() where T : Concentric, ISkill { return GetObjectOrThrow<T, ISkill, SkillDef>(); } public static Task<MusicTrackDef> GetMusicTrackDef<T>() where T : Concentric, IMusicTrack { return GetObjectOrThrow<T, IMusicTrack, MusicTrackDef>(); } public static Task<SkillFamily> GetSkillFamily<T>() where T : Concentric, ISkillFamily { return GetObjectOrThrow<T, ISkillFamily, SkillFamily>(); } public static Task<Variant> GetSkillFamilyVariant<T>() where T : Concentric, ISkill { return GetObjectOrThrow<IVariant, Variant>(GetAsset<T>()); } public static Task<GameObject> GetNetworkedObject<T>() where T : Concentric, INetworkedObject { return GetObjectOrThrow<T, INetworkedObject, GameObject>(); } public static Task<GameObject> GetGenericObject<T>() where T : Concentric, IGenericObject { return GetObjectOrThrow<T, IGenericObject, GameObject>(); } public static Task<GameObject> GetProjectile<T>() where T : Concentric, IProjectile { return GetObjectOrThrow<T, IProjectile, GameObject>(); } public static Task<GameObject> GetProjectileGhost<T>() where T : Concentric, IProjectileGhost { return GetObjectOrThrow<T, IProjectileGhost, GameObject>(); } public static Task<GameObject> GetEffect<T>() where T : Concentric, IEffect { return GetObjectOrThrow<T, IEffect, GameObject>(); } public static Task<GameObject> GetMaster<T>() where T : Concentric, IMaster { return GetObjectOrThrow<T, IMaster, GameObject>(); } public static Task<GameObject> GetBody<T>() where T : Concentric, IBody { return GetObjectOrThrow<T, IBody, GameObject>(); } public static Task<GameObject> GetBodyDisplay<T>() where T : Concentric, IBodyDisplay { return GetObjectOrThrow<T, IBodyDisplay, GameObject>(); } public static Task<GameObject> GetModel<T>() where T : Concentric, IModel { return GetObjectOrThrow<T, IModel, GameObject>(); } public static async Task<ContentPack> BuildContentPack(Assembly assembly) { ContentPack result = new ContentPack(); Type[] types = assembly.GetTypes(); foreach (Type item in types.Where((Type x) => typeof(BarData).IsAssignableFrom(x) && !x.IsAbstract)) { ExtraHealthBarSegments._barDataTypes.Add(item); } Dictionary<Type, Concentric> dictionary = types.Where((Type x) => typeof(Concentric).IsAssignableFrom(x) && !x.IsAbstract).ToDictionary((Type x) => x, (Type x) => (Concentric)Activator.CreateInstance(x)); foreach (var (key, value) in dictionary) { Assets[key] = value; } Concentric[] instances = dictionary.Values.Where((Concentric x) => x.Enabled).ToArray(); await Task.WhenAll(instances.Select((Concentric asset) => asset.Initialize())); IOverlay[] overlays = instances.Where((Concentric x) => x is IOverlay).Cast<IOverlay>().ToArray(); Overlays.AddRange(overlays); Material[] array = await Task.WhenAll(overlays.Select((IOverlay x) => GetObjectOrThrow<IOverlay, Material>((Concentric)x))); for (int i = 0; i < overlays.Length; i++) { OverlayMaterials[overlays[i]] = array[i]; } MaterialSwaps.AddRange(instances.Where((Concentric x) => x is IMaterialSwap).Cast<IMaterialSwap>()); IMaterialSwap[] swaps = instances.Where((Concentric x) => x is IMaterialSwap).Cast<IMaterialSwap>().ToArray(); MaterialSwaps.AddRange(swaps); Material[] array2 = await Task.WhenAll(swaps.Select((IMaterialSwap x) => GetObjectOrThrow<IMaterialSwap, Material>((Concentric)x))); for (int j = 0; j < overlays.Length; j++) { MaterialSwapMaterials[swaps[j]] = array2[j]; } IEnumerable<Type> entityStates = instances.Where((Concentric x) => x is IEntityStates).SelectMany((Concentric x) => (Type[])Objects.GetOrSet(x.GetType().Assembly.FullName + "_" + x.GetType().FullName + "_EntityStates", () => ((IEntityStates)x).GetEntityStates())); NamedAssetCollection<UnlockableDef> unlockableDefs = result.unlockableDefs; unlockableDefs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IUnlockable).Select(GetObjectOrThrow<IUnlockable, UnlockableDef>))); NamedAssetCollection<ItemDef> itemDefs = result.itemDefs; itemDefs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IItem).Select(GetObjectOrThrow<IItem, ItemDef>))); NamedAssetCollection<BuffDef> buffDefs = result.buffDefs; buffDefs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IBuff).Select(GetObjectOrThrow<IBuff, BuffDef>))); NamedAssetCollection<SkillDef> skillDefs = result.skillDefs; skillDefs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is ISkill).Select(GetObjectOrThrow<ISkill, SkillDef>))); result.entityStateTypes.Add(instances.Where((Concentric x) => x is ISkill).SelectMany((Concentric x) => (Type[])Objects[x.GetType().Assembly.FullName + "_" + x.GetType().FullName + "_ISkill_EntityStates"]).Concat(entityStates) .Distinct() .ToArray()); NamedAssetCollection<SkillFamily> skillFamilies = result.skillFamilies; skillFamilies.Add(await Task.WhenAll(instances.Where((Concentric x) => x is ISkillFamily).Select(GetObjectOrThrow<ISkillFamily, SkillFamily>))); NamedAssetCollection<GameObject> networkedObjectPrefabs = result.networkedObjectPrefabs; networkedObjectPrefabs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is INetworkedObject).Select(GetObjectOrThrow<INetworkedObject, GameObject>))); networkedObjectPrefabs = result.bodyPrefabs; networkedObjectPrefabs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IBody).Select(GetObjectOrThrow<IBody, GameObject>))); NamedAssetCollection<SurvivorDef> survivorDefs = result.survivorDefs; survivorDefs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is ISurvivor).Select(GetObjectOrThrow<ISurvivor, SurvivorDef>))); networkedObjectPrefabs = result.projectilePrefabs; networkedObjectPrefabs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IProjectile).Select(GetObjectOrThrow<IProjectile, GameObject>))); NamedAssetCollection<EffectDef> effectDefs = result.effectDefs; effectDefs.Add(((IEnumerable<GameObject>)(await Task.WhenAll(instances.Where((Concentric x) => x is IEffect).Select(GetObjectOrThrow<IEffect, GameObject>)))).Select((Func<GameObject, EffectDef>)((GameObject x) => new EffectDef(x))).ToArray()); networkedObjectPrefabs = result.masterPrefabs; networkedObjectPrefabs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IMaster).Select(GetObjectOrThrow<IMaster, GameObject>))); NamedAssetCollection<MusicTrackDef> musicTrackDefs = result.musicTrackDefs; musicTrackDefs.Add(await Task.WhenAll(instances.Where((Concentric x) => x is IMusicTrack).Select(GetObjectOrThrow<IMusicTrack, MusicTrackDef>))); return result; } public static bool TryGetAssetFromObject<T>(object obj, out T asset) { Concentric value; bool result = ObjectToAssetMap.TryGetValue(obj, out value); asset = ((value is T) ? ((T)(object)value) : default(T)); return result; } public static T GetAsset<T>() where T : Concentric { return (T)GetAsset(typeof(T)); } public static T GetAsset<T, T2>() where T : Concentric, T2 { return GetAsset<T>(); } public static Concentric GetAsset(Type assetType) { if (!Assets.ContainsKey(assetType)) { throw new AssetTypeInvalidException(assetType.FullName + " is not an Asset"); } return Assets[assetType]; } public static Task<T2> GetObjectOrThrow<T, T1, T2>() where T : Concentric, T1 { return GetObjectOrThrow<T1, T2>(GetAsset<T>()); } public static async Task<T2> GetObjectOrThrow<T, T2>(Concentric concentric) { return (T2)(await GetObjectOrThrow(concentric, typeof(T))); } public static Task<object> GetObjectOrThrow<T>(Concentric concentric) { return GetObjectOrThrow(concentric, typeof(T)); } public static async Task<object> GetObjectOrThrow(Concentric concentric, Type targetType) { return (await GetObjectOrNull(concentric, targetType)) ?? throw new AssetTypeInvalidException(concentric.GetType().FullName + " is not of type " + targetType.Name); } public static async Task<T2?> GetObjectOrNull<T, T1, T2>() where T : Concentric, T1 { Type typeFromHandle = typeof(T); Concentric value; return (!Assets.TryGetValue(typeFromHandle, out value)) ? default(T2) : ((await GetObjectOrNull(value, typeFromHandle) is T2 val) ? val : default(T2)); } public static async Task<T2?> GetObjectOrNull<T, T2>(Concentric concentric) { return (await GetObjectOrNull<T>(concentric) is T2 val) ? val : default(T2); } public static Task<object?> GetObjectOrNull<T>(Concentric concentric) { return GetObjectOrNull(concentric, typeof(T)); } public static Task<object?> GetObjectOrNull(Concentric concentric, Type targetType) { Type type = concentric.GetType(); string fullName = type.FullName; string name = targetType.Name; string key = type.Assembly.FullName + "_" + fullName + "_" + name; if (Tasks.TryGetValue(key, out Task<object> value)) { return value; } value = GetObjectOrNull_Internal(concentric, targetType); Tasks[key] = value; return value; } private static async Task<object?> GetObjectOrNull_Internal(Concentric concentric, Type targetType) { Type assetType = concentric.GetType(); string name = assetType.FullName; string targetTypeName = targetType.Name; string key = assetType.Assembly.FullName + "_" + name + "_" + targetTypeName; if (Objects.TryGetValue(key, out object value)) { return value; } object obj2; switch (targetTypeName) { case "ISkill": { Task<SkillDef> task2 = (concentric as ISkill)?.BuildObject(); if (task2 == null) { return null; } SkillDef obj3 = await task2; IEnumerable<Type> entityStates = ((ISkill)concentric).GetEntityStates(); Objects[key + "_EntityStates"] = entityStates; obj3.skillName = name + "SkillDef"; obj3.activationState = new SerializableEntityStateType(entityStates.FirstOrDefault()); obj2 = obj3; break; } case "IEffect": { Task<GameObject> task4 = (concentric as IEffect)?.BuildObject(); if (task4 == null) { return null; } GameObject val5 = await task4; if (!Object.op_Implicit((Object)(object)val5.GetComponent<VFXAttributes>())) { VFXAttributes obj4 = val5.AddComponent<VFXAttributes>(); obj4.vfxPriority = (VFXPriority)2; obj4.DoNotPool = true; } if (!Object.op_Implicit((Object)(object)val5.GetComponent<EffectComponent>())) { EffectComponent obj5 = val5.AddComponent<EffectComponent>(); obj5.applyScale = false; obj5.parentToReferencedTransform = true; obj5.positionAtReferencedTransform = true; } obj2 = val5; break; } case "IVariant": { Task<Variant> task3 = (concentric as IVariant)?.BuildObject(); Variant val4; if (task3 == null) { SkillDef val2 = await GetObjectOrNull<ISkill, SkillDef>(concentric); if (val2 == null) { return null; } Variant val3 = default(Variant); val3.skillDef = val2; ((Variant)(ref val3)).viewableNode = new Node(val2.skillName, false, (Node)null); val4 = val3; } else { val4 = await task3; } obj2 = val4; break; } case "ISkillFamily": { if (!(concentric is ISkillFamily familyAsset)) { return null; } SkillFamily family = await familyAsset.BuildObject(); if (family == null) { family = ScriptableObject.CreateInstance<SkillFamily>(); SkillFamily val = family; val.variants = await Task.WhenAll(familyAsset.GetSkillAssets().Select(GetObjectOrThrow<IVariant, Variant>)); } obj2 = family; break; } case "IModel": { if (!(concentric is IModel modelAsset)) { return null; } obj2 = await modelAsset.BuildObject(); Objects[key] = obj2; ObjectToAssetMap[obj2] = concentric; ModelSkinController skinController = ExtensionMethods.GetOrAddComponent<ModelSkinController>((GameObject)obj2); Task.WhenAll(modelAsset.GetSkins().Select(GetObjectOrThrow<ISkin, SkinDef>)).ContinueWith(delegate(Task<SkinDef[]> completedTask) { skinController.skins = completedTask.Result; }).ConfigureAwait(continueOnCapturedContext: false); break; } default: { object obj = targetType.GetMethod("BuildObject")?.Invoke(concentric, null); if (!(obj is Task task)) { return null; } await task; PropertyInfo property = task.GetType().GetProperty("Result"); if (property == null) { return null; } obj2 = property.GetValue(task); break; } } Type type = obj2.GetType(); Type typeFromHandle = typeof(ScriptableObject); PropertyInfo property2 = type.GetProperty("cachedName"); MethodInfo setMethod = typeFromHandle.GetProperty("name").GetSetMethod(); string text = (assetType.Name + "_" + targetTypeName).Replace(".", "_"); property2?.GetSetMethod().Invoke(obj2, new object[1] { text }); if ((object)property2 == null && typeFromHandle.IsAssignableFrom(type)) { setMethod.Invoke(obj2, new object[1] { text }); } if ("IModel" != targetTypeName && Objects.TryGetValue(key, out object value2)) { ConcentricContentPlugin.LOG.LogWarning((object)("You shouldn't be seeing this(" + key + "). It might mean a race condition, report to Concentric Content author.")); return value2; } Objects[key] = obj2; ObjectToAssetMap[obj2] = concentric; return obj2; } public virtual Task Initialize() { return Task.CompletedTask; } } public static class AssetExtensionMethods { public static Task<ItemDef> GetItemDef<T>(this T _) where T : Concentric, IItem { return Concentric.GetItemDef<T>(); } public static Task<ItemIndex> GetItemIndex<T>(this T _) where T : Concentric, IItem { return Concentric.GetItemIndex<T>(); } public static Task<UnlockableDef> GetUnlockableDef<T>(this T _) where T : Concentric, IUnlockable { return Concentric.GetUnlockableDef<T>(); } public static Task<BuffDef> GetBuffDef<T>(this T _) where T : Concentric, IBuff { return Concentric.GetBuffDef<T>(); } public static Task<BuffIndex> GetBuffIndex<T>(this T _) where T : Concentric, IBuff { return Concentric.GetBuffIndex<T>(); } public static Task<BodyIndex> GetBodyIndex<T>(this T _) where T : Concentric, IBody { return Concentric.GetBodyIndex<T>(); } public static Task<Material> GetMaterial<T>(this T _) where T : Concentric, IMaterial { return Concentric.GetMaterial<T>(); } public static Task<SurvivorDef> GetSurvivorDef<T>(this T _) where T : Concentric, ISurvivor { return Concentric.GetSurvivorDef<T>(); } public static Task<SkinDef> GetSkinDef<T>(this T _) where T : Concentric, ISkin { return Concentric.GetSkinDef<T>(); } public static Task<SkillDef> GetSkillDef<T>(this T _) where T : Concentric, ISkill { return Concentric.GetSkillDef<T>(); } public static Task<MusicTrackDef> GetMusicTrackDef<T>(this T _) where T : Concentric, IMusicTrack { return Concentric.GetMusicTrackDef<T>(); } public static Task<SkillFamily> GetSkillFamily<T>(this T _) where T : Concentric, ISkillFamily { return Concentric.GetSkillFamily<T>(); } public static Task<Variant> GetSkillFamilyVariant<T>(this T _) where T : Concentric, ISkill { return Concentric.GetSkillFamilyVariant<T>(); } public static Task<GameObject> GetNetworkedObject<T>(this T _) where T : Concentric, INetworkedObject { return Concentric.GetNetworkedObject<T>(); } public static Task<GameObject> GetGenericObject<T>(this T _) where T : Concentric, IGenericObject { return Concentric.GetGenericObject<T>(); } public static Task<GameObject> GetProjectile<T>(this T _) where T : Concentric, IProjectile { return Concentric.GetProjectile<T>(); } public static Task<GameObject> GetProjectileGhost<T>(this T _) where T : Concentric, IProjectileGhost { return Concentric.GetProjectileGhost<T>(); } public static Task<GameObject> GetEffect<T>(this T _) where T : Concentric, IEffect { return Concentric.GetEffect<T>(); } public static Task<GameObject> GetMaster<T>(this T _) where T : Concentric, IMaster { return Concentric.GetMaster<T>(); } public static Task<GameObject> GetBody<T>(this T _) where T : Concentric, IBody { return Concentric.GetBody<T>(); } public static Task<GameObject> GetBodyDisplay<T>(this T _) where T : Concentric, IBodyDisplay { return Concentric.GetBodyDisplay<T>(); } public static Task<GameObject> GetModel<T>(this T _) where T : Concentric, IModel { return Concentric.GetModel<T>(); } } public class AssetTypeInvalidException : Exception { public AssetTypeInvalidException(string message) : base(message) { } } [BepInPlugin("bubbet.concentriccontent", "ConcentricContent", "1.0.2.4")] public class ConcentricContentPlugin : BaseUnityPlugin { public static Harmony Harm; public static ConcentricContentPlugin Instance; public static ManualLogSource LOG; public const string Guid = "bubbet.concentriccontent"; public const string Version = "1.0.2.4"; public void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown Instance = this; LOG = ((BaseUnityPlugin)this).Logger; Harm = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harm.PatchAll(); } } public static class ExtensionMethods { public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component { T val = gameObject.GetComponent<T>(); if (!Object.op_Implicit((Object)(object)val)) { val = gameObject.AddComponent<T>(); } return val; } public static TV GetOrSet<TK, TV>(this Dictionary<TK, TV> dict, TK key, Func<TV> valueGetter) { if (dict.TryGetValue(key, out TV value)) { return value; } return dict[key] = valueGetter(); } } [HarmonyPatch] public static class ExtraHealthBarSegments { [RequireComponent(typeof(HealthBar))] public class ExtraHealthBarInfoTracker : MonoBehaviour { public List<BarData> BarInfos; private HealthBar? _healthBar; private Material? _defaultMaterial; public HealthBar HealthBar { get { if ((Object)(object)_healthBar == (Object)null || !Object.op_Implicit((Object)(object)_healthBar)) { _healthBar = ((Component)this).GetComponent<HealthBar>(); } return _healthBar; } } private Material DefaultMaterial { get { if ((Object)(object)_defaultMaterial == (Object)null || !Object.op_Implicit((Object)(object)_defaultMaterial)) { _defaultMaterial = ((Graphic)HealthBar.barAllocator.elementPrefab.GetComponent<Image>()).material; } return _defaultMaterial; } } public void CheckInventory(Inventory inv, CharacterBody characterBody, HealthComponent healthComponent) { foreach (BarData barInfo in BarInfos) { barInfo.CheckInventory(ref barInfo.Info, inv, characterBody, healthComponent); } } public HealthBarValues UpdateInfo(ref HealthBarValues barValues) { //IL_0013: 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) if (!Object.op_Implicit((Object)(object)HealthBar.source)) { return barValues; } foreach (BarData barInfo in BarInfos) { barInfo.UpdateInfo(ref barInfo.Info, ref barValues); } return barValues; } public void ApplyBar(ref int i) { foreach (Image element in HealthBar.barAllocator.elements) { if ((Object)(object)((Graphic)element).material != (Object)(object)DefaultMaterial) { ((Graphic)element).material = DefaultMaterial; } } foreach (BarData barInfo in BarInfos) { if (barInfo.Info.enabled) { Image image = HealthBar.barAllocator.elements[i]; barInfo.ApplyBar(ref barInfo.Info, image, ref i); } } } public void Awake() { BarInfos = _barDataTypes.Select((Type dataType) => ((BarData)Activator.CreateInstance(dataType)).Init(this)).ToList(); } } internal static List<Type> _barDataTypes = new List<Type>(); public static void AddType<T>() where T : BarData, new() { _barDataTypes.Add(typeof(T)); } [HarmonyPostfix] [HarmonyPatch(typeof(HealthBar), "Awake")] public static void AddTracker(HealthBar __instance) { ((Component)__instance).gameObject.AddComponent<ExtraHealthBarInfoTracker>(); } [HarmonyPostfix] [HarmonyPatch(typeof(HealthBar), "CheckInventory")] public static void CheckInventory(HealthBar __instance) { ExtraHealthBarInfoTracker component = ((Component)__instance).GetComponent<ExtraHealthBarInfoTracker>(); if (!Object.op_Implicit((Object)(object)component)) { return; } HealthComponent source = __instance.source; if (!Object.op_Implicit((Object)(object)source)) { return; } CharacterBody body = source.body; if (Object.op_Implicit((Object)(object)body)) { Inventory inventory = body.inventory; if (Object.op_Implicit((Object)(object)inventory)) { component.CheckInventory(inventory, body, source); } } } [HarmonyILManipulator] [HarmonyPatch(typeof(HealthBar), "UpdateBarInfos")] public static void UpdateInfos(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<HealthComponent>(x, "GetHealthBarValues") }); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<HealthBarValues, HealthBar, HealthBarValues>>((Func<HealthBarValues, HealthBar, HealthBarValues>)((HealthBarValues values, HealthBar bar) => ((Component)bar).GetComponent<ExtraHealthBarInfoTracker>().UpdateInfo(ref values))); } [HarmonyILManipulator] [HarmonyPatch(typeof(HealthBar), "ApplyBars")] public static void ApplyBar(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int cls = -1; FieldReference fld = null; val.GotoNext(new Func<Instruction, bool>[3] { (Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref cls), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0), (Instruction x) => ILPatternMatchingExt.MatchStfld(x, ref fld) }); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<BarInfoCollection>(x, "GetActiveCount") }); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<int, HealthBar, int>>((Func<int, HealthBar, int>)delegate(int i, HealthBar bar) { ExtraHealthBarInfoTracker component = ((Component)bar).GetComponent<ExtraHealthBarInfoTracker>(); i += component.BarInfos.Count((BarData x) => x.Info.enabled); return i; }); val.Index = il.Instrs.Count - 2; val.Emit(OpCodes.Ldloca, cls); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloca, cls); val.Emit(OpCodes.Ldfld, fld); val.EmitDelegate<Func<HealthBar, int, int>>((Func<HealthBar, int, int>)delegate(HealthBar bar, int i) { ((Component)bar).GetComponent<ExtraHealthBarInfoTracker>().ApplyBar(ref i); return i; }); val.Emit(OpCodes.Stfld, fld); } } public abstract class BarData { public ExtraHealthBarSegments.ExtraHealthBarInfoTracker Tracker; public BarInfo Info; public BarStyle? CachedStyle; public abstract BarStyle GetStyle(); public virtual void UpdateInfo(ref BarInfo inf, ref HealthBarValues healthBarValues) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_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_0021: Unknown result type (might be due to invalid IL or missing references) BarStyle valueOrDefault = CachedStyle.GetValueOrDefault(); if (!CachedStyle.HasValue) { valueOrDefault = GetStyle(); CachedStyle = valueOrDefault; } BarStyle value = CachedStyle.Value; inf.enabled &= value.enabled; inf.color = value.baseColor; inf.imageType = value.imageType; inf.sprite = value.sprite; inf.sizeDelta = value.sizeDelta; } public virtual void CheckInventory(ref BarInfo inf, Inventory inventory, CharacterBody characterBody, HealthComponent healthComponent) { } public virtual void ApplyBar(ref BarInfo inf, Image image, ref int i) { //IL_0002: 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_002a: 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_003b: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) image.type = inf.imageType; image.sprite = inf.sprite; ((Graphic)image).color = inf.color; RectTransform val = (RectTransform)((Component)image).transform; val.anchorMin = new Vector2(inf.normalizedXMin, 0f); val.anchorMax = new Vector2(inf.normalizedXMax, 1f); val.anchoredPosition = Vector2.zero; val.sizeDelta = new Vector2(inf.sizeDelta * 0.5f + 1f, inf.sizeDelta + 1f); i++; } public virtual BarData Init(ExtraHealthBarSegments.ExtraHealthBarInfoTracker extraHealthBarInfoTracker) { Tracker = extraHealthBarInfoTracker; return this; } } [HarmonyPatch] public class HarmonyPatches { [HarmonyILManipulator] [HarmonyPatch(typeof(Row), "FromSkillSlot")] public static void FromSkillSlot(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchNewobj<Row>(x) }); val.Emit(OpCodes.Ldarg_3); val.EmitDelegate<Func<string, GenericSkill, string>>((Func<string, GenericSkill, string>)delegate(string s, GenericSkill skill) { if (!Concentric.TryGetAssetFromObject<ISkillFamily>(skill.skillFamily, out var asset)) { return s; } string nameToken = asset.GetNameToken(skill); return (!Utility.IsNullOrWhiteSpace(nameToken)) ? nameToken : s; }); } [HarmonyPostfix] [HarmonyPatch(typeof(CharacterModel), "UpdateOverlayStates")] private static void CharacterModelUpdateOverlayStates(CharacterModel __instance, ref bool __result) { __result |= ((Component)__instance).gameObject.GetOrAddComponent<ExtraOverlayTracker>().UpdateRequired(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(CharacterModel), "UpdateOverlays")] private static void CharacterModelUpdateOverlays(CharacterModel __instance) { CharacterModel __instance2 = __instance; foreach (IOverlay item in Concentric.Overlays.Where((IOverlay overlay) => overlay.CheckEnabled(__instance2) && __instance2.activeOverlayCount < CharacterModel.maxOverlays)) { Material[] currentOverlays = __instance2.currentOverlays; CharacterModel obj = __instance2; int activeOverlayCount = obj.activeOverlayCount; obj.activeOverlayCount = activeOverlayCount + 1; currentOverlays[activeOverlayCount] = Concentric.OverlayMaterials[item]; } } [HarmonyILManipulator] [HarmonyPatch(typeof(CharacterModel), "UpdateMaterials")] public static void InjectMaterial(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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 x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterModel>(x, "UpdateRendererMaterials") })) { ConcentricContentPlugin.LOG.LogError((object)"Failed to match il in character model inject material."); return; } int index = val.Index; int iIndex = -1; if (!val.TryGotoPrev(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref iIndex) })) { return; } val.Index = index; val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc, iIndex); val.EmitDelegate<Action<CharacterModel, int>>((Action<CharacterModel, int>)delegate(CharacterModel characterModel, int i) { //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) CharacterModel characterModel2 = characterModel; RendererInfo baseRenderer = characterModel2.baseRendererInfos[i]; IMaterialSwap materialSwap = (from overlay in Concentric.MaterialSwaps where overlay.CheckEnabled(characterModel2, baseRenderer) select overlay into x orderby x.Priority select x).FirstOrDefault(); if (materialSwap != null) { characterModel2.baseRendererInfos[i].renderer.material = Concentric.MaterialSwapMaterials[materialSwap]; } }); } [HarmonyILManipulator] [HarmonyPatch(typeof(LoadoutPanelController), "Rebuild")] public static void FixLoadOutPanelControllerShowingHiddenSkillsInLoadOutTab(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel brTarget = null; int num5 = default(int); int num4 = default(int); MethodReference val3 = default(MethodReference); int num3 = default(int); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[5] { (Instruction x) => ILPatternMatchingExt.MatchBr(x, ref brTarget), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num5), (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num4), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num3) })) { ConcentricContentPlugin.LOG.LogError((object)"Failed to match il in load out panel hidden skills fix."); return; } int index = val.Index; val.Index = index - 1; val.Emit(OpCodes.Dup); index = val.Index; val.Index = index + 1; val.EmitDelegate<Func<GenericSkill, bool>>((Func<GenericSkill, bool>)((GenericSkill skill) => Concentric.TryGetAssetFromObject<ISkillFamily>(skill.skillFamily, out var asset) && asset.HiddenFromCharacterSelect)); ILLabel val2 = val.DefineLabel(); val.Emit(OpCodes.Brtrue, (object)val2); val.Goto(brTarget.Target, (MoveType)0, false); int num2 = default(int); int num = default(int); val.GotoPrev(new Func<Instruction, bool>[4] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num2), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 1), (Instruction x) => ILPatternMatchingExt.MatchAdd(x), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num) }); val.MarkLabel(val2); } } public class ExtraOverlayTracker : MonoBehaviour { private readonly Dictionary<IOverlay, bool> wasEnabled = new Dictionary<IOverlay, bool>(); public bool UpdateRequired(CharacterModel model) { bool result = false; foreach (IOverlay overlay in Concentric.Overlays) { bool flag = overlay.CheckEnabled(model); if (!wasEnabled.TryGetValue(overlay, out var value) || flag != value) { wasEnabled[overlay] = flag; result = true; } } return result; } } public interface IGameObject { } public interface IGenericObject : IGameObject { Task<GameObject> BuildObject(); } public interface INetworkedObject : IGameObject { Task<GameObject> BuildObject(); } public interface IProjectile : IGameObject { Task<GameObject> BuildObject(); } public interface IProjectileGhost : IGameObject { Task<GameObject> BuildObject(); } public interface IEffect : IGameObject { Task<GameObject> BuildObject(); } public interface IMaster : IGameObject { Task<GameObject> BuildObject(); } public interface IBody : IGameObject { Task<GameObject> BuildObject(); } public interface IBodyDisplay : IGameObject { Task<GameObject> BuildObject(); } public interface IModel : IGameObject { Task<GameObject> BuildObject(); IEnumerable<Concentric> GetSkins(); } public interface ISurvivor { Task<SurvivorDef> BuildObject(); } public interface ISkin { Task<SkinDef> BuildObject(); static void AddDefaults(ref SkinDef skinDef) { SkinDef val = skinDef; if (val.baseSkins == null) { val.baseSkins = Array.Empty<SkinDef>(); } val = skinDef; if (val.gameObjectActivations == null) { val.gameObjectActivations = Array.Empty<GameObjectActivation>(); } val = skinDef; if (val.meshReplacements == null) { val.meshReplacements = Array.Empty<MeshReplacement>(); } val = skinDef; if (val.minionSkinReplacements == null) { val.minionSkinReplacements = Array.Empty<MinionSkinReplacement>(); } val = skinDef; if (val.projectileGhostReplacements == null) { val.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(); } } } public interface IItem { Task<ItemDef> BuildObject(); } public interface IMaterial { Task<Material> BuildObject(); } public interface IOverlay { Task<Material> BuildObject(); bool CheckEnabled(CharacterModel model); } public interface IMaterialSwap { int Priority { get; } Task<Material> BuildObject(); bool CheckEnabled(CharacterModel model, RendererInfo targetRendererInfo); } public interface IUnlockable { Task<UnlockableDef> BuildObject(); } public interface IMusicTrack { Task<MusicTrackDef> BuildObject(); } public interface IBuff { Task<BuffDef> BuildObject(); } public interface ISkillFamily { bool HiddenFromCharacterSelect => false; Task<SkillFamily> BuildObject() { return Task.FromResult<SkillFamily>(null); } IEnumerable<Concentric> GetSkillAssets(); string GetNameToken(GenericSkill skill) { return ""; } } public interface ISkill { Task<SkillDef> BuildObject(); IEnumerable<Type> GetEntityStates(); } public interface IEntityStates { IEnumerable<Type> GetEntityStates(); } public interface IVariant { Task<Variant> BuildObject(); } }