using 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ConcentricContent")]
[assembly: AssemblyConfiguration("Debug")]
[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 barData in types.Where((Type x) => typeof(BarData).IsAssignableFrom(x) && !x.IsAbstract))
{
ExtraHealthBarSegments._barDataTypes.Add(barData);
}
IEnumerable<Type> assets = types.Where((Type x) => typeof(Concentric).IsAssignableFrom(x) && !x.IsAbstract);
Dictionary<Type, Concentric> localAssets = assets.ToDictionary((Type x) => x, (Type x) => (Concentric)Activator.CreateInstance(x));
foreach (var (key, value) in localAssets)
{
Assets[key] = value;
}
Concentric[] instances = localAssets.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[] materialsOL = await Task.WhenAll(overlays.Select((IOverlay x) => GetObjectOrThrow<IOverlay, Material>((Concentric)x)));
for (int i = 0; i < overlays.Length; i++)
{
OverlayMaterials[overlays[i]] = materialsOL[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[] materialsSW = await Task.WhenAll(swaps.Select((IMaterialSwap x) => GetObjectOrThrow<IMaterialSwap, Material>((Concentric)x)));
for (int j = 0; j < overlays.Length; j++)
{
MaterialSwapMaterials[swaps[j]] = materialsSW[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>)));
NamedAssetCollection<GameObject> bodyPrefabs = result.bodyPrefabs;
bodyPrefabs.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>)));
NamedAssetCollection<GameObject> projectilePrefabs = result.projectilePrefabs;
projectilePrefabs.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());
NamedAssetCollection<GameObject> masterPrefabs = result.masterPrefabs;
masterPrefabs.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 assetType = typeof(T);
Concentric asset;
return (!Assets.TryGetValue(assetType, out asset)) ? default(T2) : ((await GetObjectOrNull(asset, assetType) is T2 result) ? result : default(T2));
}
public static async Task<T2?> GetObjectOrNull<T, T2>(Concentric concentric)
{
return (await GetObjectOrNull<T>(concentric) is T2 result) ? result : 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 result))
{
return result;
}
object returnedObject;
switch (targetTypeName)
{
case "ISkill":
{
Task<SkillDef> skillTask = (concentric as ISkill)?.BuildObject();
if (skillTask == null)
{
return null;
}
SkillDef skill = await skillTask;
IEnumerable<Type> entityStates = ((ISkill)concentric).GetEntityStates();
Objects[key + "_EntityStates"] = entityStates;
skill.skillName = name + "SkillDef";
skill.activationState = new SerializableEntityStateType(entityStates.FirstOrDefault());
returnedObject = skill;
break;
}
case "IEffect":
{
Task<GameObject> effectTask = (concentric as IEffect)?.BuildObject();
if (effectTask == null)
{
return null;
}
GameObject effect = await effectTask;
if (!Object.op_Implicit((Object)(object)effect.GetComponent<VFXAttributes>()))
{
VFXAttributes attributes = effect.AddComponent<VFXAttributes>();
attributes.vfxPriority = (VFXPriority)2;
attributes.DoNotPool = true;
}
if (!Object.op_Implicit((Object)(object)effect.GetComponent<EffectComponent>()))
{
EffectComponent comp = effect.AddComponent<EffectComponent>();
comp.applyScale = false;
comp.parentToReferencedTransform = true;
comp.positionAtReferencedTransform = true;
}
returnedObject = effect;
break;
}
case "IVariant":
{
Task<Variant> variantTask = (concentric as IVariant)?.BuildObject();
Variant variant;
if (variantTask == null)
{
SkillDef skillDef = await GetObjectOrNull<ISkill, SkillDef>(concentric);
if (skillDef == null)
{
return null;
}
Variant val2 = new Variant
{
skillDef = skillDef
};
((Variant)(ref val2)).viewableNode = new Node(skillDef.skillName, false, (Node)null);
variant = val2;
}
else
{
variant = await variantTask;
}
returnedObject = variant;
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>));
}
returnedObject = family;
break;
}
case "IModel":
{
if (!(concentric is IModel modelAsset))
{
return null;
}
returnedObject = await modelAsset.BuildObject();
Objects[key] = returnedObject;
ObjectToAssetMap[returnedObject] = concentric;
ModelSkinController skinController = ExtensionMethods.GetOrAddComponent<ModelSkinController>((GameObject)returnedObject);
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 taskType = task.GetType().GetProperty("Result");
if (taskType == null)
{
return null;
}
returnedObject = taskType.GetValue(task);
break;
}
}
Type returnedType = returnedObject.GetType();
Type scriptableObject = typeof(ScriptableObject);
PropertyInfo cachedName = returnedType.GetProperty("cachedName");
MethodInfo nameProperty = scriptableObject.GetProperty("name").GetSetMethod();
string objectName = (assetType.Name + "_" + targetTypeName).Replace(".", "_");
cachedName?.GetSetMethod().Invoke(returnedObject, new object[1] { objectName });
if ((object)cachedName == null && scriptableObject.IsAssignableFrom(returnedType))
{
nameProperty.Invoke(returnedObject, new object[1] { objectName });
}
if ("IModel" != targetTypeName && Objects.TryGetValue(key, out object existingObject))
{
ConcentricContentPlugin.LOG.LogWarning((object)("You shouldn't be seeing this(" + key + "). It might mean a race condition, report to Concentric Content author."));
return existingObject;
}
Objects[key] = returnedObject;
ObjectToAssetMap[returnedObject] = concentric;
return returnedObject;
}
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.0")]
public class ConcentricContentPlugin : BaseUnityPlugin
{
public static Harmony Harm;
public static ConcentricContentPlugin Instance;
public static ManualLogSource LOG;
public const string Guid = "bubbet.concentriccontent";
public void Awake()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: 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 = null;
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_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_0069: 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)
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_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0039: 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>)delegate(HealthBarValues values, HealthBar bar)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
ExtraHealthBarInfoTracker component = ((Component)bar).GetComponent<ExtraHealthBarInfoTracker>();
return component.UpdateInfo(ref values);
});
}
[HarmonyILManipulator]
[HarmonyPatch(typeof(HealthBar), "ApplyBars")]
public static void ApplyBar(ILContext il)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_009a: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: 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)
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 component2 = ((Component)bar).GetComponent<ExtraHealthBarInfoTracker>();
i += component2.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)
{
ExtraHealthBarInfoTracker component = ((Component)bar).GetComponent<ExtraHealthBarInfoTracker>();
component.ApplyBar(ref i);
return i;
});
val.Emit(OpCodes.Stfld, fld);
}
}
public abstract class BarData
{
public ExtraHealthBarSegments.ExtraHealthBarInfoTracker Tracker = null;
public BarInfo Info;
public BarStyle? CachedStyle;
public abstract BarStyle GetStyle();
public virtual void UpdateInfo(ref BarInfo inf, ref HealthBarValues healthBarValues)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: 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_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: 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_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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_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)
//IL_0022: 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_0003: 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_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: 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)
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_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: 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(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) ? s : nameToken;
});
}
[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_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
ILCursor val = new ILCursor(il);
if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
{
(Instruction 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_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)
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_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
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.Emit(OpCodes.Ldfld, typeof(GenericSkill).GetField("hideInCharacterSelect"));
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
{
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();
}
}