Decompiled source of MoonstormSharedUtils v2.2.2
plugins/MSU.Runtime.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using HG; using HG.Reflection; using IL.RoR2; using JetBrains.Annotations; using LoadingScreenFix; using MSU; using MSU.AddressReferencedAssets; using MSU.Config; using Mono.Cecil.Cil; using MonoMod.Cil; using Newtonsoft.Json; using On.RoR2; using On.RoR2.Items; using On.RoR2.UI; using R2API; using R2API.AddressReferencedAssets; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.ScriptableObjects; using RiskOfOptions; using RiskOfOptions.Components.Panel; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Achievements; using RoR2.ContentManagement; using RoR2.EntitlementManagement; using RoR2.ExpansionManagement; using RoR2.Items; using RoR2.Projectile; using RoR2.Skills; using RoR2.UI; using RoR2BepInExPack.VanillaFixes; using ShaderSwapper; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.Serialization; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: InternalsVisibleTo("MoonstormSharedUtils", AllInternalsVisible = true)] [assembly: InternalsVisibleTo("MSU.Editor", AllInternalsVisible = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace EntityStates.GameplayEvents { public class GameplayEventState : EntityState { public GameplayEvent gameplayEvent { get; private set; } public override void OnEnter() { ((EntityState)this).OnEnter(); gameplayEvent = ((EntityState)this).GetComponent<GameplayEvent>(); } } } namespace MSU { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class AsyncAssetLoadAttribute : SearchableAttribute { public MethodInfo targetMethodInfo => ((SearchableAttribute)this).target as MethodInfo; [Obsolete("Use \"CreateParallelCoroutineForMod\"")] public static ParallelMultiStartCoroutine CreateCoroutineForMod(BaseUnityPlugin plugin) { List<SearchableAttribute> instances = SearchableAttribute.GetInstances<AsyncAssetLoadAttribute>(); if (instances == null) { return new ParallelMultiStartCoroutine(); } return CreateMultiStartCoroutineForMod((from att in instances.Where(IsValid) where IsFromMod((AsyncAssetLoadAttribute)(object)att, plugin) select att).Cast<AsyncAssetLoadAttribute>().ToList()); } public static ParallelCoroutine CreateParallelCoroutineForMod(BaseUnityPlugin plugin) { List<SearchableAttribute> instances = SearchableAttribute.GetInstances<AsyncAssetLoadAttribute>(); if (instances == null) { return new ParallelCoroutine(); } return CreateCoroutineForMod((from att in instances.Where(IsValid) where IsFromMod((AsyncAssetLoadAttribute)(object)att, plugin) select att).Cast<AsyncAssetLoadAttribute>().ToList()); } [Obsolete] private static ParallelMultiStartCoroutine CreateMultiStartCoroutineForMod(List<AsyncAssetLoadAttribute> attributes) { ParallelMultiStartCoroutine parallelMultiStartCoroutine = new ParallelMultiStartCoroutine(); foreach (AsyncAssetLoadAttribute attribute in attributes) { parallelMultiStartCoroutine.Add((Func<IEnumerator>)attribute.targetMethodInfo.CreateDelegate(typeof(Func<IEnumerator>))); } return parallelMultiStartCoroutine; } private static ParallelCoroutine CreateCoroutineForMod(List<AsyncAssetLoadAttribute> attributes) { ParallelCoroutine parallelCoroutine = new ParallelCoroutine(); foreach (AsyncAssetLoadAttribute attribute in attributes) { parallelCoroutine.Add((IEnumerator)attribute.targetMethodInfo.Invoke(null, null)); } return parallelCoroutine; } private static bool IsValid(SearchableAttribute _att) { if (!(_att is AsyncAssetLoadAttribute asyncAssetLoadAttribute)) { return false; } MethodInfo methodInfo = asyncAssetLoadAttribute.targetMethodInfo; if (!methodInfo.IsStatic) { MSULog.Info($"{asyncAssetLoadAttribute} is not applied to a Static method", 86, "IsValid"); } Type returnType = methodInfo.ReturnType; if (returnType == null || returnType == typeof(void)) { return false; } returnType.IsSameOrSubclassOf(typeof(IEnumerator)); if (methodInfo.GetGenericArguments().Length != 0) { return false; } return true; } private static bool IsFromMod(AsyncAssetLoadAttribute attribute, BaseUnityPlugin plugin) { return attribute.targetMethodInfo.DeclaringType.Assembly == ((object)plugin).GetType().Assembly; } public override string ToString() { return "AsyncAssetLoadAttribute(TargetMethod=" + targetMethodInfo.DeclaringType.FullName + "." + targetMethodInfo.Name + "())"; } } public abstract class BaseBuffBehaviour : MonoBehaviour { [AttributeUsage(AttributeTargets.Method)] public class BuffDefAssociation : SearchableAttribute { } private int _buffCount; public int buffCount { get { return _buffCount; } internal set { if (_buffCount != value) { int num = _buffCount; _buffCount = value; if (num == 0 && _buffCount > 0) { ((Behaviour)this).enabled = true; OnFirstStackGained(); } if (num > 0 && _buffCount == 0) { ((Behaviour)this).enabled = false; OnAllStacksLost(); } } } } public BuffIndex buffIndex { get; internal set; } public CharacterBody characterBody { get; internal set; } public bool hasAnyStacks => _buffCount > 0; protected virtual void OnFirstStackGained() { } protected virtual void OnAllStacksLost() { } protected virtual void Awake() { characterBody = ((Component)this).GetComponent<CharacterBody>(); } protected virtual void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) MSUContentManagement.OnBuffBehaviourDestroyed(characterBody, buffIndex); } } public abstract class BaseItemMasterBehaviour : MonoBehaviour { private struct NetworkContextSet { public ItemTypePair[] itemTypePairs; public FixedSizeArrayPool<BaseItemMasterBehaviour> behaviorArraysPool; public void SetItemTypePairs(List<ItemTypePair> itemTypePairs) { this.itemTypePairs = itemTypePairs.ToArray(); behaviorArraysPool = new FixedSizeArrayPool<BaseItemMasterBehaviour>(this.itemTypePairs.Length); } } [MeansImplicitUse] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class ItemDefAssociationAttribute : SearchableAttribute { public Type behaviorTypeOverride; public bool useOnServer = true; public bool useOnClient = true; } public int stack; private static NetworkContextSet _server; private static NetworkContextSet _client; private static NetworkContextSet _shared; private static CharacterMaster _earlyAssignmentMaster = null; private static Dictionary<UnityObjectWrapperKey<CharacterMaster>, BaseItemMasterBehaviour[]> _masterToItemBehaviors = new Dictionary<UnityObjectWrapperKey<CharacterMaster>, BaseItemMasterBehaviour[]>(); public CharacterMaster master { get; private set; } protected virtual void Awake() { master = _earlyAssignmentMaster; _earlyAssignmentMaster = null; } [SystemInitializer(new Type[] { typeof(ItemCatalog) })] private static IEnumerator Init() { MSULog.Info("Initializing the BaseItemMasterBehaviour system...", 37, "Init"); List<ItemTypePair> server = new List<ItemTypePair>(); List<ItemTypePair> client = new List<ItemTypePair>(); List<ItemTypePair> shared = new List<ItemTypePair>(); List<ItemDefAssociationAttribute> list = new List<ItemDefAssociationAttribute>(); SearchableAttribute.GetInstances<ItemDefAssociationAttribute>(list); Type masterBehaviourType = typeof(BaseItemMasterBehaviour); Type itemDefType = typeof(ItemDef); foreach (ItemDefAssociationAttribute itemDefAssociationAttribute in list) { yield return null; MethodInfo methodInfo; if ((methodInfo = ((SearchableAttribute)itemDefAssociationAttribute).target as MethodInfo) == null) { MSULog.Error("ItemDefAssociationAttribute cannot be applied to object of type '" + ((object)itemDefAssociationAttribute)?.GetType().FullName + "'", 52, "Init"); continue; } if (!methodInfo.IsStatic) { MSULog.Error("ItemDefAssociationAttribute cannot be applied to method " + methodInfo.DeclaringType.FullName + "." + methodInfo.Name + ": Method is not static.", 56, "Init"); continue; } Type type = itemDefAssociationAttribute.behaviorTypeOverride ?? methodInfo.DeclaringType; if (!masterBehaviourType.IsAssignableFrom(type)) { MSULog.Error("ItemDefAssociationAttribute cannot be applied to method " + methodInfo.DeclaringType.FullName + "." + methodInfo.Name + ": " + methodInfo.DeclaringType.FullName + " does not derive from " + masterBehaviourType.FullName + ".", 70, "Init"); continue; } if (type.IsAbstract) { MSULog.Error("ItemDefAssociationAttribute cannot be applied to method " + methodInfo.DeclaringType.FullName + "." + methodInfo.Name + ": " + methodInfo.DeclaringType.FullName + " is an abstract type.", 85, "Init"); continue; } if (!itemDefType.IsAssignableFrom(methodInfo.ReturnType)) { object[] array = new object[7] { "ItemDefAssociationAttribute", methodInfo.DeclaringType.FullName, methodInfo.Name, methodInfo.DeclaringType.FullName, methodInfo, null, null }; int num = 5; Type returnType = methodInfo.ReturnType; array[num] = ((returnType != null) ? returnType.FullName : null) ?? "void"; array[6] = itemDefType.FullName; MSULog.Error(string.Format("{0} cannot be applied to method {1}.{2}: {3}.{4} returns type '{5}' instead of {6}.", array), 109, "Init"); continue; } if (methodInfo.GetGenericArguments().Length != 0) { MSULog.Error(string.Format("{0} cannot be applied to method {1}.{2}: {3}.{4} must take no arguments.", "ItemDefAssociationAttribute", methodInfo.DeclaringType.FullName, methodInfo.Name, methodInfo.DeclaringType.FullName, methodInfo), 113, "Init"); continue; } ItemDef val = (ItemDef)methodInfo.Invoke(null, Array.Empty<object>()); if (!Object.op_Implicit((Object)(object)val)) { MSULog.Error(methodInfo.DeclaringType.FullName + "." + methodInfo.Name + " returned null.", 127, "Init"); continue; } if ((int)val.itemIndex < 0) { MSULog.Error($"{methodInfo.DeclaringType.FullName}.{methodInfo.Name} returned an ItemDef that's not registered in the ItemCatalog. result={val}", 131, "Init"); continue; } if (itemDefAssociationAttribute.useOnServer) { server.Add(new ItemTypePair { itemIndex = val.itemIndex, behaviorType = type }); } if (itemDefAssociationAttribute.useOnClient) { client.Add(new ItemTypePair { itemIndex = val.itemIndex, behaviorType = type }); } if (itemDefAssociationAttribute.useOnServer || itemDefAssociationAttribute.useOnClient) { shared.Add(new ItemTypePair { itemIndex = val.itemIndex, behaviorType = type }); } } _server.SetItemTypePairs(server); _client.SetItemTypePairs(client); _shared.SetItemTypePairs(shared); if (server.Count != 0 || client.Count != 0 || shared.Count != 0) { CharacterMaster.Awake += new hook_Awake(CharacterMaster_Awake); CharacterMaster.OnDestroy += new hook_OnDestroy(CharacterMaster_OnDestroy); CharacterMaster.OnInventoryChanged += new hook_OnInventoryChanged(CharacterMaster_OnInventoryChanged); } } private static void CharacterMaster_Awake(orig_Awake orig, CharacterMaster self) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) BaseItemMasterBehaviour[] value = GetNetworkContext().behaviorArraysPool.Request(); _masterToItemBehaviors.Add(UnityObjectWrapperKey<CharacterMaster>.op_Implicit(self), value); orig.Invoke(self); } private static void CharacterMaster_OnDestroy(orig_OnDestroy orig, CharacterMaster self) { //IL_000d: 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) orig.Invoke(self); BaseItemMasterBehaviour[] array = _masterToItemBehaviors[UnityObjectWrapperKey<CharacterMaster>.op_Implicit(self)]; for (int i = 0; i < array.Length; i++) { Object.Destroy((Object)(object)array[i]); } _masterToItemBehaviors.Remove(UnityObjectWrapperKey<CharacterMaster>.op_Implicit(self)); if (NetworkServer.active || NetworkClient.active) { GetNetworkContext().behaviorArraysPool.Return(array, (ClearType<BaseItemMasterBehaviour>)0); } } private static void CharacterMaster_OnInventoryChanged(orig_OnInventoryChanged orig, CharacterMaster self) { orig.Invoke(self); UpdateMasterItemBehaviorStacks(self); } private static ref NetworkContextSet GetNetworkContext() { bool active = NetworkServer.active; bool active2 = NetworkClient.active; if (active) { if (active2) { return ref _shared; } return ref _server; } if (active2) { return ref _client; } throw new InvalidOperationException("Neither server nor client is running."); } private static void UpdateMasterItemBehaviorStacks(CharacterMaster master) { //IL_000c: 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_004d: 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_0057: Unknown result type (might be due to invalid IL or missing references) ref NetworkContextSet networkContext = ref GetNetworkContext(); if (!_masterToItemBehaviors.TryGetValue(UnityObjectWrapperKey<CharacterMaster>.op_Implicit(master), out var value)) { return; } ItemTypePair[] itemTypePairs = networkContext.itemTypePairs; Inventory inventory = master.inventory; if (Object.op_Implicit((Object)(object)inventory)) { for (int i = 0; i < itemTypePairs.Length; i++) { ItemTypePair val = itemTypePairs[i]; SetItemStack(master, ref value[i], val.behaviorType, inventory.GetItemCount(val.itemIndex)); } return; } for (int j = 0; j < itemTypePairs.Length; j++) { ref BaseItemMasterBehaviour reference = ref value[j]; if ((Object)(object)reference != (Object)null) { Object.Destroy((Object)(object)reference); reference = null; } } } private static void SetItemStack(CharacterMaster master, ref BaseItemMasterBehaviour behavior, Type behaviorType, int stack) { if ((Object)(object)behavior == (Object)null != stack <= 0) { if (stack <= 0) { behavior.stack = 0; Object.Destroy((Object)(object)behavior); behavior = null; } else { _earlyAssignmentMaster = master; behavior = (BaseItemMasterBehaviour)(object)((Component)master).gameObject.AddComponent(behaviorType); _earlyAssignmentMaster = null; } } if ((Object)(object)behavior != (Object)null) { behavior.stack = stack; } } } public sealed class GameplayEvent : NetworkBehaviour { [Tooltip("When set to true, this gameplay event will call \"StartEvent\" on it's Start method")] [SyncVar] public bool beginOnStart; [Header("Gameplay Event Metadata")] [SyncVar] [Tooltip("When the event does an announcement, the announcement duration of the text will be this value. This value can be overwritten by the GameplayEventManager's spawn method at runtime.")] [SerializeField] private float _announcementDuration = 6f; [SerializeField] [SyncVar] [Tooltip("Is this value is greater than 0, the event will automatically stop once it has existed for this duration.")] private float _eventDuration = -1f; [Tooltip("When the event starts, this Token is used to inform the players.")] [SerializeField] private string _eventStartToken; [Tooltip("When the event starts, this sound effect is played to inform the players.")] [SerializeField] private NetworkSoundEventDef _eventStartSfx; [Tooltip("When the event ends, this token is used to inform the players.")] [SerializeField] private string _eventEndToken; [Tooltip("When the event ends, this sound effect is played to inform the players.")] [SerializeField] private NetworkSoundEventDef _eventEndSfx; [Tooltip("This color is used for the messages displayed when the event starts and ends. An outline color is calculated automatically.")] [SerializeField] private Color _eventColor; [Space] [Header("Gameplay Event Hooks")] [Tooltip("Called when this specific event begins")] [SerializeField] private UnityGameplayEvent _onEventStart; [Tooltip("Called when this specific event ends")] [SerializeField] private UnityGameplayEvent _onEventEnd; [SyncVar(hook = "Client_OnIsPlayingChanged")] private bool _isPlaying; [SyncVar] private bool _doNotAnnounceStart; [SyncVar] private bool _doNotAnnounceEnd; private float _eventDurationStopwatch; public float announcementDuration { get { return _announcementDuration; } set { Network_announcementDuration = value; } } public float eventDuration { get { return _eventDuration; } set { Network_eventDuration = value; } } public string eventStartToken => _eventStartToken; public NetworkSoundEventDef eventStartSfx => _eventStartSfx; public string eventEndToken => _eventEndToken; public NetworkSoundEventDef eventEndSfx => _eventEndSfx; public Color eventColor => _eventColor; [field: NonSerialized] public GameplayEventIndex gameplayEventIndex { get; internal set; } public bool isPlaying { get { return _isPlaying; } private set { Network_isPlaying = value; } } public bool doNotAnnounceStart { get { return _doNotAnnounceStart; } set { Network_doNotAnnounceStart = value; } } public bool doNotAnnounceEnd { get { return _doNotAnnounceEnd; } set { Network_doNotAnnounceEnd = value; } } public EntityStateIndex? customTextStateIndex { get; set; } public GenericObjectIndex? customTMPFontAssetIndex { get; set; } public NullableRef<GameplayEventRequirement> gameplayEventRequirement { get; private set; } public bool NetworkbeginOnStart { get { return beginOnStart; } [param: In] set { ((NetworkBehaviour)this).SetSyncVar<bool>(value, ref beginOnStart, 1u); } } public float Network_announcementDuration { get { return _announcementDuration; } [param: In] set { ((NetworkBehaviour)this).SetSyncVar<float>(value, ref _announcementDuration, 2u); } } public float Network_eventDuration { get { return _eventDuration; } [param: In] set { ((NetworkBehaviour)this).SetSyncVar<float>(value, ref _eventDuration, 4u); } } public bool Network_isPlaying { get { return _isPlaying; } [param: In] set { ref bool reference = ref _isPlaying; if (NetworkServer.localClientActive && !((NetworkBehaviour)this).syncVarHookGuard) { ((NetworkBehaviour)this).syncVarHookGuard = true; Client_OnIsPlayingChanged(value); ((NetworkBehaviour)this).syncVarHookGuard = false; } ((NetworkBehaviour)this).SetSyncVar<bool>(value, ref reference, 8u); } } public bool Network_doNotAnnounceStart { get { return _doNotAnnounceStart; } [param: In] set { ((NetworkBehaviour)this).SetSyncVar<bool>(value, ref _doNotAnnounceStart, 16u); } } public bool Network_doNotAnnounceEnd { get { return _doNotAnnounceEnd; } [param: In] set { ((NetworkBehaviour)this).SetSyncVar<bool>(value, ref _doNotAnnounceEnd, 32u); } } public static event GameplayEventDelegate onEventStartServer; public static event GameplayEventDelegate onEventStartGlobal; public event GameplayEventDelegate onEventStart; public static event GameplayEventDelegate onEventEndServer; public static event GameplayEventDelegate onEventEndGlobal; public event GameplayEventDelegate onEventEnd; private void Awake() { InstanceTracker.Add<GameplayEvent>(this); gameplayEventRequirement = ((Component)this).GetComponent<GameplayEventRequirement>(); } private void Start() { if (beginOnStart && !isPlaying && NetworkServer.active) { StartEvent(); } } private void OnDestroy() { if (isPlaying && NetworkServer.active) { EndEvent(); } InstanceTracker.Remove<GameplayEvent>(this); } [Server] public void StartEvent() { if (!NetworkServer.active) { Debug.LogWarning((object)"[Server] function 'System.Void MSU.GameplayEvent::StartEvent()' called on client"); } else if (!isPlaying) { _eventDurationStopwatch = 0f; isPlaying = true; GameplayEvent.onEventStartServer?.Invoke(this); GameplayEvent.onEventStartGlobal?.Invoke(this); this.onEventStart?.Invoke(this); ((UnityEvent<GameplayEvent>)_onEventStart)?.Invoke(this); AnnounceEvent(); } } private void FixedUpdate() { if (NetworkServer.active && !(eventDuration < 0f) && isPlaying) { _eventDurationStopwatch += Time.fixedDeltaTime; if (_eventDurationStopwatch > eventDuration) { EndEvent(); } } } [Server] public void EndEvent() { if (!NetworkServer.active) { Debug.LogWarning((object)"[Server] function 'System.Void MSU.GameplayEvent::EndEvent()' called on client"); } else if (isPlaying) { _eventDurationStopwatch = 0f; isPlaying = false; GameplayEvent.onEventEndServer?.Invoke(this); GameplayEvent.onEventEndGlobal?.Invoke(this); this.onEventEnd?.Invoke(this); ((UnityEvent<GameplayEvent>)_onEventEnd)?.Invoke(this); AnnounceEvent(); } } private void AnnounceEvent() { //IL_0052: 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_00ad: 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) if ((!isPlaying || !doNotAnnounceStart) && (isPlaying || !doNotAnnounceEnd) && Object.op_Implicit((Object)(object)GameplayEventTextController.instance)) { GameplayEventTextController.EventTextRequest request = default(GameplayEventTextController.EventTextRequest); if (customTextStateIndex.HasValue) { request.customTextState = new SerializableEntityStateType(EntityStateCatalog.GetStateType(customTextStateIndex.Value)); } if (customTMPFontAssetIndex.HasValue) { request.genericObjectIndexThatPointsToTMP_FontAsset = customTMPFontAssetIndex.Value; } request.textDuration = announcementDuration; request.eventToken = eventStartToken; request.eventColor = eventColor; GameplayEventTextController.instance.EnqueueNewTextRequest(request, sendOverNetwork: false); } } [Client] private void Client_OnIsPlayingChanged(bool newVal) { if (!NetworkClient.active) { Debug.LogWarning((object)"[Client] function 'System.Void MSU.GameplayEvent::Client_OnIsPlayingChanged(System.Boolean)' called on server"); return; } if (newVal) { GameplayEvent.onEventStartGlobal?.Invoke(this); this.onEventStart?.Invoke(this); ((UnityEvent<GameplayEvent>)_onEventStart).Invoke(this); } else { GameplayEvent.onEventEndGlobal?.Invoke(this); this.onEventEnd?.Invoke(this); ((UnityEvent<GameplayEvent>)_onEventEnd)?.Invoke(this); } AnnounceEvent(); } public override bool OnSerialize(NetworkWriter writer, bool initialState) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!initialState) { return false; } writer.Write(customTextStateIndex.HasValue); if (customTextStateIndex.HasValue) { NetworkExtensions.Write(writer, customTextStateIndex.Value); } writer.Write(customTMPFontAssetIndex.HasValue); if (customTMPFontAssetIndex.HasValue) { writer.Write(customTMPFontAssetIndex.Value); } return true; } public override void OnDeserialize(NetworkReader reader, bool initialState) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (initialState) { if (reader.ReadBoolean()) { customTextStateIndex = NetworkExtensions.ReadEntityStateIndex(reader); } if (reader.ReadBoolean()) { customTMPFontAssetIndex = reader.ReadGenericObjectIndex(); } } } private void UNetVersion() { } public override void PreStartClient() { } } [Serializable] public class UnityGameplayEvent : UnityEvent<GameplayEvent> { } public delegate void GameplayEventDelegate(GameplayEvent gameplayEvent); [RequireComponent(typeof(GameplayEvent))] public class GameplayEventRequirement : MonoBehaviour { [Tooltip("At least this amount of stages should be completed before this GameplayEvent can spawn")] public int minimumStageCompletions = -1; [Tooltip("At least someone in the player team needs to have this unlockable unlocked before this GameplayEvent can spawn")] public AddressReferencedUnlockableDef requiredUnlockable; [Tooltip("None of the players should have this unlockable unlocked before this GameplayEvent can spawn")] public AddressReferencedUnlockableDef forbiddenUnlockable; [Tooltip("These ExpansionDefs need to be enabled in the run for this GameplayEvent to spawn")] public List<AddressReferencedExpansionDef> requiredExpansions; [Tooltip("The teleporter's charge needs to be bellow this value for a GameplayEvent to spawn")] [Range(0f, 1f)] public float maximumTeleportCharge = 0.25f; public GameplayEvent gameplayEvent { get; private set; } protected virtual void Awake() { gameplayEvent = ((Component)this).GetComponent<GameplayEvent>(); } public virtual bool IsAvailable() { if (!Object.op_Implicit((Object)(object)Run.instance)) { return false; } if (CheckStageCompletions() && CheckUnlockables() && CheckExpansions()) { return CheckTeleporterCharge(); } return false; } protected bool CheckStageCompletions() { if (!Object.op_Implicit((Object)(object)Run.instance)) { return false; } if (minimumStageCompletions == -1) { return true; } return Run.instance.stageClearCount > minimumStageCompletions; } protected bool CheckUnlockables() { bool num = !AddressReferencedUnlockableDef.op_Implicit(requiredUnlockable) || Run.instance.IsUnlockableUnlocked(AddressReferencedUnlockableDef.op_Implicit(requiredUnlockable)); bool flag = AddressReferencedUnlockableDef.op_Implicit(forbiddenUnlockable) && Run.instance.DoesEveryoneHaveThisUnlockableUnlocked(AddressReferencedUnlockableDef.op_Implicit(forbiddenUnlockable)); if (num) { return !flag; } return false; } protected bool CheckExpansions() { foreach (AddressReferencedExpansionDef requiredExpansion in requiredExpansions) { if (AddressReferencedExpansionDef.op_Implicit(requiredExpansion) && !Run.instance.IsExpansionEnabled(AddressReferencedExpansionDef.op_Implicit(requiredExpansion))) { return false; } } return true; } protected bool CheckTeleporterCharge() { if (!Object.op_Implicit((Object)(object)TeleporterInteraction.instance)) { return true; } return TeleporterInteraction.instance.chargeFraction < maximumTeleportCharge; } } public sealed class GameplayEventTextController : MonoBehaviour { public struct EventTextRequest { public string eventToken; public Color eventColor; public float textDuration; public SerializableEntityStateType? customTextState; public GenericObjectIndex genericObjectIndexThatPointsToTMP_FontAsset; public string tokenValue => Language.GetString(eventToken); public Color GetBestOutlineColor() { //IL_0001: 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) float num = default(float); float num2 = default(float); float num3 = default(float); Color.RGBToHSV(eventColor, ref num, ref num2, ref num3); float num4 = ((num3 > 0.5f) ? (-0.5f) : 0.5f); float num5 = Mathf.Clamp01(num2 + num4); float num6 = Mathf.Clamp01(num3 + num4); return Color.HSVToRGB(num, num5, num6); } } public abstract class EventTextState : EntityState { public float duration; public GameplayEventTextController textController { get; private set; } public UIJuice uiJuice { get; private set; } public override void OnEnter() { ((EntityState)this).OnEnter(); textController = ((EntityState)this).GetComponent<GameplayEventTextController>(); uiJuice = ((EntityState)this).GetComponent<UIJuice>(); } protected virtual void NullRequest() { textController.NullCurrentRequest(); } } public class FadeInState : EventTextState { public override void OnEnter() { base.OnEnter(); base.uiJuice.destroyOnEndOfTransition = false; base.uiJuice.transitionDuration = duration; base.uiJuice.TransitionAlphaFadeIn(); base.uiJuice.originalAlpha = MSUConfig._maxOpacityForEventMessage; base.uiJuice.transitionEndAlpha = 1f; } public override void Update() { ((EntityState)this).Update(); if (((EntityState)this).age > duration) { ((EntityState)this).outer.SetNextState((EntityState)(object)new WaitState { duration = duration }); } } } public class WaitState : EventTextState { public override void Update() { ((EntityState)this).Update(); if (((EntityState)this).age > duration) { ((EntityState)this).outer.SetNextState((EntityState)(object)new FadeOutState { duration = duration }); } } } public class FadeOutState : EventTextState { public override void OnEnter() { base.OnEnter(); base.uiJuice.TransitionAlphaFadeOut(); } public override void Update() { ((EntityState)this).Update(); if (((EntityState)this).age > duration) { base.textController.NullCurrentRequest(); ((EntityState)this).outer.SetNextStateToMain(); } } } internal class SendEventTextRequestToClientsMessage : INetMessage, ISerializableObject { public EventTextRequest request; public void Deserialize(NetworkReader reader) { //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_004e: 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) request = default(EventTextRequest); request.eventToken = reader.ReadString(); request.eventColor = reader.ReadColor(); request.textDuration = reader.ReadSingle(); if (reader.ReadBoolean()) { request.customTextState = new SerializableEntityStateType(EntityStateCatalog.GetStateType(NetworkExtensions.ReadEntityStateIndex(reader))); } request.genericObjectIndexThatPointsToTMP_FontAsset = reader.ReadGenericObjectIndex(); } public void OnReceived() { instance.EnqueueNewTextRequest(request, sendOverNetwork: false); } public void Serialize(NetworkWriter writer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) //IL_0074: Unknown result type (might be due to invalid IL or missing references) writer.Write(request.eventToken); writer.Write(request.eventColor); writer.Write(request.textDuration); writer.Write(request.customTextState.HasValue); if (request.customTextState.HasValue) { SerializableEntityStateType value = request.customTextState.Value; NetworkExtensions.Write(writer, EntityStateCatalog.GetStateIndex(((SerializableEntityStateType)(ref value)).stateType)); } writer.Write(request.genericObjectIndexThatPointsToTMP_FontAsset); } public SendEventTextRequestToClientsMessage(EventTextRequest request) { this.request = request; } public SendEventTextRequestToClientsMessage() { } } private static GameObject _prefab; private Queue<EventTextRequest> _textRequests = new Queue<EventTextRequest>(); private TMP_FontAsset _bombadierFontAsset; public static GameplayEventTextController instance { get; private set; } public EntityStateMachine textStateMachine { get; private set; } public HGTextMeshProUGUI textMeshProUGUI { get; private set; } public HUD hudInstance { get; private set; } public EventTextRequest? currentTextRequest { get; private set; } public RectTransform rectTransform { get; private set; } [SystemInitializer(new Type[] { })] private static IEnumerator SystemInit() { MSULog.Info("Initializing the GameplayEventTextController...", 59, "SystemInit"); AssetBundleRequest request = MSUMain.msuAssetBundle.LoadAssetAsync<GameObject>("GameplayEventText"); while (!((AsyncOperation)request).isDone) { yield return null; } Object asset = request.asset; _prefab = (GameObject)(object)((asset is GameObject) ? asset : null); HUD.Awake += new hook_Awake(SpawnAndGetInstance); MSUConfig._eventMessageFontSize.onConfigChanged += SetTextSize; MSUConfig._familyEventUsesEventAnnouncementInsteadOfChatMessage.onConfigChanged += ShouldAnnounceFamilyEventsAsGameplayEvents; NetworkingAPI.RegisterMessageType<SendEventTextRequestToClientsMessage>(); } private static void ShouldAnnounceFamilyEventsAsGameplayEvents(bool announceAsGameplayEvents) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (announceAsGameplayEvents) { ClassicStageInfo.BroadcastFamilySelection -= new hook_BroadcastFamilySelection(BroadcastFamilySelection); ClassicStageInfo.BroadcastFamilySelection += new hook_BroadcastFamilySelection(BroadcastFamilySelection); } else { ClassicStageInfo.BroadcastFamilySelection -= new hook_BroadcastFamilySelection(BroadcastFamilySelection); } } private static IEnumerator BroadcastFamilySelection(orig_BroadcastFamilySelection orig, ClassicStageInfo self, string familySelectionChatString) { if (!Object.op_Implicit((Object)(object)instance)) { yield return orig.Invoke(self, familySelectionChatString); yield break; } yield return (object)new WaitForSeconds(6f); instance.EnqueueNewTextRequest(new EventTextRequest { eventColor = Color.white, eventToken = familySelectionChatString, textDuration = 6f }, sendOverNetwork: true); } private static void SetTextSize(float newVal) { if (Object.op_Implicit((Object)(object)instance)) { ((TMP_Text)instance.textMeshProUGUI).fontSize = newVal; ((TMP_Text)instance.textMeshProUGUI).fontSizeMax = newVal; } } private static void SpawnAndGetInstance(orig_Awake orig, HUD self) { orig.Invoke(self); Object.Instantiate<GameObject>(_prefab, self.mainContainer.transform); instance.hudInstance = self; } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CC_TestEventText(ConCommandArgs args) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)instance)) { instance.EnqueueNewTextRequest(new EventTextRequest { eventToken = "Event Text Test", eventColor = Color.cyan, textDuration = 15f }, sendOverNetwork: true); } } public void EnqueueNewTextRequest(EventTextRequest request, bool sendOverNetwork) { if (sendOverNetwork) { SendRequestOverNetwork(request); } else { _textRequests.Enqueue(request); } } private void SendRequestOverNetwork(EventTextRequest request) { NetMessageExtensions.Send((INetMessage)(object)new SendEventTextRequestToClientsMessage(request), (NetworkDestination)3); } private void Update() { //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) if (!currentTextRequest.HasValue && _textRequests.Count > 0) { DequeueAndInitializeRequest(); } else if (currentTextRequest.HasValue && textStateMachine.state is Idle) { EventTextRequest value = currentTextRequest.Value; bool hasValue = value.customTextState.HasValue; EventTextState eventTextState = null; if (hasValue) { SerializableEntityStateType value2 = value.customTextState.Value; eventTextState = (EventTextState)(object)EntityStateCatalog.InstantiateState(ref value2); } else { eventTextState = new FadeInState(); } eventTextState.duration = (hasValue ? value.textDuration : (value.textDuration / 3f)); textStateMachine.SetNextState((EntityState)(object)eventTextState); } } internal void NullCurrentRequest() { currentTextRequest = null; } private void DequeueAndInitializeRequest() { //IL_003e: 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_0057: 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) //IL_0090: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) currentTextRequest = _textRequests.Dequeue(); string tokenValue = currentTextRequest.Value.tokenValue; Color eventColor = currentTextRequest.Value.eventColor; Color bestOutlineColor = currentTextRequest.Value.GetBestOutlineColor(); GenericObjectIndex genericObjectIndexThatPointsToTMP_FontAsset = currentTextRequest.Value.genericObjectIndexThatPointsToTMP_FontAsset; ((TMP_Text)textMeshProUGUI).text = tokenValue; ((Graphic)textMeshProUGUI).color = eventColor; ((TMP_Text)textMeshProUGUI).outlineColor = Color32.op_Implicit(bestOutlineColor); ((TMP_Text)textMeshProUGUI).font = ((genericObjectIndexThatPointsToTMP_FontAsset == GenericObjectIndex.None) ? HGTextMeshProUGUI.defaultLanguageFont : GenericUnityObjectCatalog.GetObject<TMP_FontAsset>(genericObjectIndexThatPointsToTMP_FontAsset)); rectTransform.anchoredPosition = Vector2.op_Implicit(new Vector3((float)MSUConfig._eventMessageXOffset, (float)MSUConfig._eventMessageYOffset)); } private void Start() { _bombadierFontAsset = ((TMP_Text)textMeshProUGUI).font; } private void Awake() { textStateMachine = ((Component)this).GetComponent<EntityStateMachine>(); textMeshProUGUI = ((Component)this).GetComponent<HGTextMeshProUGUI>(); rectTransform = ((Component)this).GetComponent<RectTransform>(); } private void OnEnable() { instance = this; ((TMP_Text)textMeshProUGUI).text = string.Empty; } private void OnDisable() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } public class ItemTierPickupDisplayHelper : MonoBehaviour { private PickupDisplay _display; private GameObject _vfxInstance; private void Awake() { _display = ((Component)this).GetComponent<PickupDisplay>(); } public void RebuildCustomModel() { //IL_0014: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_002f: 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) if (!Object.op_Implicit((Object)(object)_display)) { return; } PickupDef pickupDef = PickupCatalog.GetPickupDef(_display.pickupIndex); if (pickupDef == null) { return; } ItemTier itemTier = pickupDef.itemTier; if ((int)itemTier > 10) { ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(itemTier); if (Object.op_Implicit((Object)(object)itemTierDef) && ItemTierModule._itemTierToPickupFX.TryGetValue(itemTierDef, out var value) && Object.op_Implicit((Object)(object)value)) { _vfxInstance = Object.Instantiate<GameObject>(value, ((Component)_display).transform); _vfxInstance.transform.position = Vector3.zero; } } } public void DestroyCustomModel() { if (Object.op_Implicit((Object)(object)_vfxInstance)) { Object.Destroy((Object)(object)_vfxInstance); } } } public sealed class MSUContentBehaviour : MonoBehaviour { public CharacterBody body; public MSUEliteBehaviour eliteBehaviour; private IStatItemBehavior[] _statItemBehaviors = Array.Empty<IStatItemBehavior>(); private IBodyStatArgModifier[] _bodyStatArgModifiers = Array.Empty<IBodyStatArgModifier>(); public bool hasMaster { get; private set; } private void Start() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) hasMaster = Object.op_Implicit((Object)(object)body.master); body.onInventoryChanged += CheckEquipmentAndStartGetInterfaces; EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)((!Object.op_Implicit((Object)(object)body.inventory)) ? (-1) : ((int)body.inventory.GetEquipmentIndex()))); if (Object.op_Implicit((Object)(object)equipmentDef) && EquipmentModule.allMoonstormEquipments.TryGetValue(equipmentDef, out var value)) { value.OnEquipmentObtained(body); if (Object.op_Implicit((Object)(object)equipmentDef.passiveBuffDef) && equipmentDef.passiveBuffDef.isElite) { eliteBehaviour.AssignNewIndex(equipmentDef.passiveBuffDef.eliteDef.eliteIndex); } } StartGetInterfaces(); } private void CheckEquipmentAndStartGetInterfaces() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) StartGetInterfaces(); if (!hasMaster) { return; } EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(body.inventory.GetEquipmentIndex()); if (Object.op_Implicit((Object)(object)equipmentDef) && Object.op_Implicit((Object)(object)eliteBehaviour)) { if (!Object.op_Implicit((Object)(object)equipmentDef.passiveBuffDef) || !equipmentDef.passiveBuffDef.isElite) { eliteBehaviour.AssignNewIndex((EliteIndex)(-1)); } else { eliteBehaviour.AssignNewIndex(equipmentDef.passiveBuffDef.eliteDef.eliteIndex); } } } public void StartGetInterfaces() { ((MonoBehaviour)this).StartCoroutine(GetInterfaces()); } private IEnumerator GetInterfaces() { yield return null; _statItemBehaviors = ((Component)this).GetComponents<IStatItemBehavior>(); _bodyStatArgModifiers = ((Component)this).GetComponents<IBodyStatArgModifier>(); body.healthComponent.onIncomingDamageReceivers = ((Component)this).GetComponents<IOnIncomingDamageServerReceiver>(); body.healthComponent.onTakeDamageReceivers = ((Component)this).GetComponents<IOnTakeDamageServerReceiver>(); } internal void GetStatCoefficients(StatHookEventArgs args) { for (int i = 0; i < _bodyStatArgModifiers.Length; i++) { _bodyStatArgModifiers[i].ModifyStatArguments(args); } } internal void RecalculateStatsStart() { for (int i = 0; i < _statItemBehaviors.Length; i++) { _statItemBehaviors[i].RecalculateStatsStart(); } } internal void RecalculateStatsEnd() { for (int i = 0; i < _statItemBehaviors.Length; i++) { _statItemBehaviors[i].RecalculateStatsEnd(); } } private void OnDestroy() { Object.Destroy((Object)(object)eliteBehaviour); } } public sealed class MSUEliteBehaviour : MonoBehaviour { public CharacterBody body; public CharacterModel characterModel; private GameObject _effectInstance; private EliteIndex _assignedIndex = (EliteIndex)(-1); internal void AssignNewIndex(EliteIndex index) { //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_000b: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (_assignedIndex == index) { return; } _assignedIndex = index; if ((int)_assignedIndex == -1) { if (Object.op_Implicit((Object)(object)_effectInstance)) { Object.Destroy((Object)(object)_effectInstance); } return; } if (Object.op_Implicit((Object)(object)_effectInstance)) { Object.Destroy((Object)(object)_effectInstance); } if (EquipmentModule.eliteIndexToEffectPrefab.TryGetValue(index, out var value)) { _effectInstance = Object.Instantiate<GameObject>(value, Object.op_Implicit((Object)(object)characterModel) ? ((Component)characterModel).transform : (Object.op_Implicit((Object)(object)body) ? body.transform : ((Component)this).transform), false); } } private void OnDestroy() { if (Object.op_Implicit((Object)(object)_effectInstance)) { Object.Destroy((Object)(object)_effectInstance); } } } public interface IArtifactContentPiece : IContentPiece<ArtifactDef>, IContentPiece { NullableRef<ArtifactCode> artifactCode { get; } void OnArtifactEnabled(); void OnArtifactDisabled(); } public interface ICharacterContentPiece : IGameObjectContentPiece<CharacterBody>, IContentPiece<GameObject>, IContentPiece { NullableRef<GameObject> masterPrefab { get; } } public interface IEliteContentPiece : IEquipmentContentPiece, IContentPiece<EquipmentDef>, IContentPiece { List<EliteDef> eliteDefs { get; } } public interface IEquipmentContentPiece : IContentPiece<EquipmentDef>, IContentPiece { NullableRef<List<GameObject>> itemDisplayPrefabs { get; } bool Execute(EquipmentSlot slot); void OnEquipmentObtained(CharacterBody body); void OnEquipmentLost(CharacterBody body); } public interface IInteractableContentPiece : IGameObjectContentPiece<IInteractable>, IContentPiece<GameObject>, IContentPiece { NullableRef<InteractableCardProvider> cardProvider { get; } } public interface IItemContentPiece : IContentPiece<ItemDef>, IContentPiece { NullableRef<List<GameObject>> itemDisplayPrefabs { get; } } public interface IItemTierContentPiece : IContentPiece<ItemTierDef>, IContentPiece { NullableRef<SerializableColorCatalogEntry> colorIndex { get; } NullableRef<SerializableColorCatalogEntry> darkColorIndex { get; } GameObject pickupDisplayVFX { get; } List<ItemIndex> itemsWithThisTier { get; set; } List<PickupIndex> availableTierDropList { get; set; } } public interface IMonsterContentPiece : ICharacterContentPiece, IGameObjectContentPiece<CharacterBody>, IContentPiece<GameObject>, IContentPiece { NullableRef<MonsterCardProvider> cardProvider { get; } NullableRef<DirectorCardHolderExtended> dissonanceCard { get; } } public interface ISceneContentPiece : IContentPiece<SceneDef>, IContentPiece { NullableRef<MusicTrackDef> mainTrack { get; } NullableRef<MusicTrackDef> bossTrack { get; } NullableRef<Texture2D> bazaarTextureBase { get; } float? weightRelativeToSiblings { get; } bool? preLoop { get; } bool? postLoop { get; } void OnServerStageComplete(Stage stage); void OnServerStageBegin(Stage stage); } public interface ISurvivorContentPiece : ICharacterContentPiece, IGameObjectContentPiece<CharacterBody>, IContentPiece<GameObject>, IContentPiece { SurvivorDef survivorDef { get; } } public interface IVanillaSurvivorContentPiece : IContentPiece { SurvivorDef survivorDef { get; } IEnumerator InitializeAsync(); } public interface IVoidItemContentPiece : IItemContentPiece, IContentPiece<ItemDef>, IContentPiece { List<ItemDef> GetInfectableItems(); } public interface IContentPackModifier { void ModifyContentPack(ContentPack contentPack); } public interface IContentPiece { IEnumerator LoadContentAsync(); bool IsAvailable(ContentPack contentPack); void Initialize(); } public interface IContentPiece<T> : IContentPiece where T : Object { T asset { get; } } public interface IContentPieceProvider { ContentPack contentPack { get; } IContentPiece[] GetContents(); } public interface IContentPieceProvider<T> : IContentPieceProvider where T : Object { new IContentPiece<T>[] GetContents(); } public interface IGameObjectContentPiece<T> : IContentPiece<GameObject>, IContentPiece { T component { get; } } public static class ContentUtil { private class ContentPieceProvider : IContentPieceProvider { private ContentPack _contentPack; private IContentPiece[] _contentPieces; public ContentPack contentPack => _contentPack; public IContentPiece[] GetContents() { return _contentPieces; } public ContentPieceProvider(IEnumerable<IContentPiece> contentPieces, ContentPack contentPack) { _contentPieces = contentPieces.ToArray(); _contentPack = contentPack; } } private class GenericContentPieceProvider<T> : IContentPieceProvider<T>, IContentPieceProvider where T : Object { private ContentPack _contentPack; private IContentPiece<T>[] _contentPieces; public ContentPack contentPack => _contentPack; public IContentPiece<T>[] GetContents() { return _contentPieces; } IContentPiece[] IContentPieceProvider.GetContents() { return _contentPieces; } public GenericContentPieceProvider(IEnumerable<IContentPiece<T>> contentPieces, ContentPack contentPack) { _contentPieces = contentPieces.ToArray(); _contentPack = contentPack; } } private static ExpansionDef _dummyExpansion = ScriptableObject.CreateInstance<ExpansionDef>(); public static void DisableArtifact(ArtifactDef artifactDef) { artifactDef.requiredExpansion = _dummyExpansion; } public static void DisableSurvivor(SurvivorDef survivorDef) { survivorDef.hidden = true; } public static void DisableItem(ItemDef itemDef) { itemDef.requiredExpansion = _dummyExpansion; } public static void DisableEquipment(EquipmentDef equipmentDef) { equipmentDef.requiredExpansion = _dummyExpansion; } public static IContentPieceProvider CreateContentPieceProvider<TContentPieceType>(BaseUnityPlugin plugin, ContentPack contentPack) where TContentPieceType : IContentPiece { return new ContentPieceProvider(AnalyzeForContentPieces<TContentPieceType>(plugin).OfType<IContentPiece>(), contentPack); } public static IEnumerable<TContentPieceType> AnalyzeForContentPieces<TContentPieceType>(BaseUnityPlugin plugin) where TContentPieceType : IContentPiece { return from t in ReflectionCache.GetTypes(((object)plugin).GetType().Assembly).Where(PassesFilterForContentPieceInterface<TContentPieceType>) select (TContentPieceType)Activator.CreateInstance(t); } public static IContentPieceProvider<TUObjectType> CreateGenericContentPieceProvider<TUObjectType>(BaseUnityPlugin baseUnityPlugin, ContentPack contentPack) where TUObjectType : Object { return new GenericContentPieceProvider<TUObjectType>(AnalyzeForGenericContentPieces<TUObjectType>(baseUnityPlugin), contentPack); } public static IEnumerable<IContentPiece<TUObjectType>> AnalyzeForGenericContentPieces<TUObjectType>(BaseUnityPlugin baseUnityPlugin) where TUObjectType : Object { return from t in ReflectionCache.GetTypes(((object)baseUnityPlugin).GetType().Assembly).Where(PassesFilterForObjectType<TUObjectType>) select (IContentPiece<TUObjectType>)Activator.CreateInstance(t); } public static IContentPieceProvider<GameObject> CreateGameObjectGenericContentPieceProvider<TComponentType>(BaseUnityPlugin baseUnityPlugin, ContentPack contentPack) { return new GenericContentPieceProvider<GameObject>(AnalyzeForGameObjectGenericContentPieces<TComponentType>(baseUnityPlugin), contentPack); } public static IEnumerable<IContentPiece<GameObject>> AnalyzeForGameObjectGenericContentPieces<TComponentTYpe>(BaseUnityPlugin baseUnityPlugin) { return from t in ReflectionCache.GetTypes(((object)baseUnityPlugin).GetType().Assembly) where PassesFilterForObjectType<GameObject>(t) && t.GetInterfaces().Contains(typeof(IGameObjectContentPiece<TComponentTYpe>)) select (IContentPiece<GameObject>)Activator.CreateInstance(t); } public static void AddSingle<T>(this NamedAssetCollection<T> collection, T content) where T : class { //IL_006c: Unknown result type (might be due to invalid IL or missing references) string text = collection.nameProvider(content); string text2 = $"{content.GetType().Name}_{collection.Count}"; if (!collection.assetToName.ContainsKey(content)) { if (Utility.IsNullOrWhiteSpace(text)) { text = text2; } collection.nameToAsset.ContainsKey(text); _ = 1; _ = collection.assetInfos.Length; ref AssetInfo<T>[] assetInfos = ref collection.assetInfos; AssetInfo<T> val = new AssetInfo<T> { asset = content, assetName = text }; ArrayUtils.ArrayAppend<AssetInfo<T>>(ref assetInfos, ref val); collection.nameToAsset[text] = content; collection.assetToName[content] = text; Array.Sort(collection.assetInfos); } } public static void PopulateTypeFields<TAsset>(Type typeToPopulate, NamedAssetCollection<TAsset> assets) where TAsset : Object { string[] array = new string[assets.Length]; for (int i = 0; i < assets.Length; i++) { array[i] = ((Object)assets[i]).name; } int num = 0; FieldInfo[] fields = typeToPopulate.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType.IsSameOrSubclassOf(typeof(TAsset))) { string name = fieldInfo.Name; TAsset val = assets.Find(name); if ((Object)(object)val != (Object)null) { fieldInfo.SetValue(null, val); } else { num++; } } } } public static void AddContentFromAssetCollection(this ContentPack contentPack, AssetCollection assetCollection) { AddContentFromCollectionInternal(contentPack, assetCollection.assets); } public static void AddContentFromAssetCollection(this ContentPack contentPack, AssetCollection assetCollection, Func<Object, bool> predicate) { Object[] assetCollection2 = assetCollection.assets.Where(predicate).ToArray(); AddContentFromCollectionInternal(contentPack, assetCollection2); } public static TAsset FindAsset<TAsset>(this AssetCollection collection, string assetName) where TAsset : Object { return (from asset in collection.assets.OfType<TAsset>() where string.Equals(((Object)asset).name, assetName, StringComparison.OrdinalIgnoreCase) select asset).FirstOrDefault(); } public static TAsset[] FindAssets<TAsset>(this AssetCollection collection) where TAsset : Object { return collection.assets.OfType<TAsset>().ToArray(); } private static void AddContentFromCollectionInternal(ContentPack contentPack, Object[] assetCollection) { foreach (Object val in assetCollection) { try { if (Object.op_Implicit(val)) { HandleAssetAddition(val, contentPack); } } catch (Exception data) { MSULog.Error(data, 341, "AddContentFromCollectionInternal"); } } } private static void HandleAssetAddition(Object asset, ContentPack contentPack) { GameObject val = (GameObject)(object)((asset is GameObject) ? asset : null); if (val == null) { SkillDef val2 = (SkillDef)(object)((asset is SkillDef) ? asset : null); if (val2 == null) { SkillFamily val3 = (SkillFamily)(object)((asset is SkillFamily) ? asset : null); if (val3 == null) { SceneDef val4 = (SceneDef)(object)((asset is SceneDef) ? asset : null); if (val4 == null) { ItemDef val5 = (ItemDef)(object)((asset is ItemDef) ? asset : null); if (val5 == null) { ItemTierDef val6 = (ItemTierDef)(object)((asset is ItemTierDef) ? asset : null); if (val6 == null) { ItemRelationshipProvider val7 = (ItemRelationshipProvider)(object)((asset is ItemRelationshipProvider) ? asset : null); if (val7 == null) { ItemRelationshipType val8 = (ItemRelationshipType)(object)((asset is ItemRelationshipType) ? asset : null); if (val8 == null) { EquipmentDef val9 = (EquipmentDef)(object)((asset is EquipmentDef) ? asset : null); if (val9 == null) { BuffDef val10 = (BuffDef)(object)((asset is BuffDef) ? asset : null); if (val10 == null) { EliteDef val11 = (EliteDef)(object)((asset is EliteDef) ? asset : null); if (val11 == null) { UnlockableDef val12 = (UnlockableDef)(object)((asset is UnlockableDef) ? asset : null); if (val12 == null) { SurvivorDef val13 = (SurvivorDef)(object)((asset is SurvivorDef) ? asset : null); if (val13 == null) { ArtifactDef val14 = (ArtifactDef)(object)((asset is ArtifactDef) ? asset : null); if (val14 == null) { SurfaceDef val15 = (SurfaceDef)(object)((asset is SurfaceDef) ? asset : null); if (val15 == null) { NetworkSoundEventDef val16 = (NetworkSoundEventDef)(object)((asset is NetworkSoundEventDef) ? asset : null); if (val16 == null) { MusicTrackDef val17 = (MusicTrackDef)(object)((asset is MusicTrackDef) ? asset : null); if (val17 == null) { GameEndingDef val18 = (GameEndingDef)(object)((asset is GameEndingDef) ? asset : null); if (val18 == null) { EntityStateConfiguration val19 = (EntityStateConfiguration)(object)((asset is EntityStateConfiguration) ? asset : null); if (val19 == null) { ExpansionDef val20 = (ExpansionDef)(object)((asset is ExpansionDef) ? asset : null); if (val20 == null) { EntitlementDef val21 = (EntitlementDef)(object)((asset is EntitlementDef) ? asset : null); if (val21 == null) { MiscPickupDef val22 = (MiscPickupDef)(object)((asset is MiscPickupDef) ? asset : null); if (val22 == null) { if (asset is EntityStateTypeCollection collection) { AddEntityStateTypes(collection, contentPack); } } else { contentPack.miscPickupDefs.AddSingle<MiscPickupDef>(val22); } } else { contentPack.entitlementDefs.AddSingle<EntitlementDef>(val21); } } else { contentPack.expansionDefs.AddSingle<ExpansionDef>(val20); } } else { contentPack.entityStateConfigurations.AddSingle<EntityStateConfiguration>(val19); } } else { contentPack.gameEndingDefs.AddSingle<GameEndingDef>(val18); } } else { contentPack.musicTrackDefs.AddSingle<MusicTrackDef>(val17); } } else { contentPack.networkSoundEventDefs.AddSingle<NetworkSoundEventDef>(val16); } } else { contentPack.surfaceDefs.AddSingle<SurfaceDef>(val15); } } else { contentPack.artifactDefs.AddSingle<ArtifactDef>(val14); } } else { contentPack.survivorDefs.AddSingle<SurvivorDef>(val13); } } else { contentPack.unlockableDefs.AddSingle<UnlockableDef>(val12); } } else { contentPack.eliteDefs.AddSingle<EliteDef>(val11); } } else { contentPack.buffDefs.AddSingle<BuffDef>(val10); } } else { contentPack.equipmentDefs.AddSingle<EquipmentDef>(val9); } } else { contentPack.itemRelationshipTypes.AddSingle<ItemRelationshipType>(val8); } } else { contentPack.itemRelationshipProviders.AddSingle<ItemRelationshipProvider>(val7); } } else { contentPack.itemTierDefs.AddSingle<ItemTierDef>(val6); } } else { contentPack.itemDefs.AddSingle<ItemDef>(val5); } } else { contentPack.sceneDefs.AddSingle<SceneDef>(val4); } } else { contentPack.skillFamilies.AddSingle<SkillFamily>(val3); } } else { contentPack.skillDefs.AddSingle<SkillDef>(val2); } } else { HandleGameObjectAddition(val, contentPack); } } private static void HandleGameObjectAddition(GameObject go, ContentPack contentPack) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown NetworkIdentity component = go.GetComponent<NetworkIdentity>(); bool flag = false; CharacterBody val = default(CharacterBody); if (go.TryGetComponent<CharacterBody>(ref val)) { flag = true; contentPack.bodyPrefabs.AddSingle<GameObject>(go); } CharacterMaster val2 = default(CharacterMaster); if (go.TryGetComponent<CharacterMaster>(ref val2)) { flag = true; contentPack.masterPrefabs.AddSingle<GameObject>(go); } ProjectileController val3 = default(ProjectileController); if (go.TryGetComponent<ProjectileController>(ref val3)) { flag = true; contentPack.projectilePrefabs.AddSingle<GameObject>(go); } Run val4 = default(Run); if (go.TryGetComponent<Run>(ref val4)) { flag = true; contentPack.gameModePrefabs.AddSingle<GameObject>(go); } EffectComponent val5 = default(EffectComponent); if (go.TryGetComponent<EffectComponent>(ref val5)) { contentPack.effectDefs.AddSingle<EffectDef>(new EffectDef(go)); } if (Object.op_Implicit((Object)(object)component) && !flag) { contentPack.networkedObjectPrefabs.AddSingle<GameObject>(go); } } private static void AddEntityStateTypes(EntityStateTypeCollection collection, ContentPack contentPack) { //IL_000d: 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) SerializableEntityStateType[] stateTypes = collection.stateTypes; for (int i = 0; i < stateTypes.Length; i++) { SerializableEntityStateType val = stateTypes[i]; if (((SerializableEntityStateType)(ref val)).stateType != null) { contentPack.entityStateTypes.AddSingle(((SerializableEntityStateType)(ref val)).stateType); } } } private static bool PassesFilterForContentPieceInterface<TContentPieceInterface>(Type t) where TContentPieceInterface : IContentPiece { bool num = !t.IsAbstract; bool flag = t.GetInterfaces().Contains(typeof(TContentPieceInterface)); return num && flag; } private static bool PassesFilterForObjectType<T>(Type t) where T : Object { bool num = !t.IsAbstract; bool flag = t.GetInterfaces().Contains(typeof(IContentPiece<T>)); return num && flag; } } [Obsolete("Use ParallelCoroutine instead, calling all the enumerator methods at the same frame makes no difference in terms of code execution")] public class ParallelMultiStartCoroutine : IEnumerator { private struct Wrapper { public Delegate coroutineDelegate; public object[] args; public IEnumerator coroutine; } private List<Wrapper> _wrappers = new List<Wrapper>(); private IEnumerator _internalCoroutine; public bool isDone { get { if (_internalCoroutine == null) { Start(); } return _internalCoroutine.IsDone(); } } object IEnumerator.Current => _internalCoroutine.Current; public void Start() { for (int i = 0; i < _wrappers.Count; i++) { Wrapper value = _wrappers[i]; value.coroutine = (IEnumerator)(value.coroutineDelegate?.DynamicInvoke(value.args)); _wrappers[i] = value; } _internalCoroutine = InternalCoroutine(); } public void Add(Func<IEnumerator> func) { _wrappers.Add(new Wrapper { coroutineDelegate = func }); } public void Add<T1>(Func<T1, IEnumerator> func, T1 arg) { _wrappers.Add(new Wrapper { coroutineDelegate = func, args = new object[1] { arg } }); } public void Add<T1, T2>(Func<T1, T2, IEnumerator> func, T1 arg1, T2 arg2) { _wrappers.Add(new Wrapper { coroutineDelegate = func, args = new object[2] { arg1, arg2 } }); } public void Add<T1, T2, T3>(Func<T1, T2, T3, IEnumerator> func, T1 arg1, T2 arg2, T3 arg3) { _wrappers.Add(new Wrapper { coroutineDelegate = func, args = new object[3] { arg1, arg2, arg3 } }); } public void Add<T1, T2, T3, T4>(Func<T1, T2, T3, T4, IEnumerator> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { _wrappers.Add(new Wrapper { coroutineDelegate = func, args = new object[4] { arg1, arg2, arg3, arg4 } }); } public void Add<T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, IEnumerator> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) { _wrappers.Add(new Wrapper { coroutineDelegate = func, args = new object[5] { arg1, arg2, arg3, arg4, arg5 } }); } private IEnumerator InternalCoroutine() { yield return null; bool encounteredUnfinished = true; while (encounteredUnfinished) { encounteredUnfinished = false; for (int i = _wrappers.Count - 1; i >= 0; i--) { Wrapper wrapper = _wrappers[i]; if (!wrapper.coroutine.IsDone()) { encounteredUnfinished = true; yield return wrapper.coroutine.Current; } else { _wrappers.RemoveAt(i); } } } } bool IEnumerator.MoveNext() { if (_internalCoroutine == null) { Start(); } return _internalCoroutine?.MoveNext() ?? false; } void IEnumerator.Reset() { if (_internalCoroutine == null) { Start(); } _internalCoroutine?.MoveNext(); } } public class ParallelCoroutine : IEnumerator { private readonly List<IEnumerator> _coroutinesList = new List<IEnumerator>(); private IEnumerator _internalCoroutine; public bool isDone => this.IsDone(); public object Current => _internalCoroutine.Current; public ParallelCoroutine() { _internalCoroutine = InternalCoroutine(); } public void Add(IEnumerator coroutine) { _coroutinesList.Add(coroutine); } public bool MoveNext() { return _internalCoroutine.MoveNext(); } public void Reset() { _internalCoroutine.Reset(); } private IEnumerator InternalCoroutine() { yield return null; bool encounteredUnfinished = true; while (encounteredUnfinished) { encounteredUnfinished = false; int i = _coroutinesList.Count - 1; while (i >= 0) { IEnumerator enumerator = _coroutinesList[i]; if (enumerator.MoveNext()) { encounteredUnfinished = true; yield return enumerator.Current; } else { _coroutinesList.RemoveAt(i); } int num = i - 1; i = num; } } } } public class DirectorCardHolderExtended : DirectorCardHolder { public ExpansionDef[] requiredExpansionDefs = Array.Empty<ExpansionDef>(); public bool IsAvailable() { if (base.Card.IsAvailable()) { return ExpansionRequirementMet(); } return false; } public bool ExpansionRequirementMet() { ExpansionDef[] enabledExpansions = Run.instance.GetEnabledExpansions(); ExpansionDef[] array = requiredExpansionDefs; foreach (ExpansionDef value in array) { if (!enabledExpansions.Contains(value)) { return false; } } return true; } } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct CharacterBodyIndexEqualityComparer : IEqualityComparer<CharacterBody> { public bool Equals(CharacterBody x, CharacterBody y) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)y)) { return false; } if ((int)x.bodyIndex == -1 || (int)y.bodyIndex == -1) { return false; } return x.bodyIndex == y.bodyIndex; } public int GetHashCode(CharacterBody obj) { return ((object)obj).GetHashCode(); } } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct IInteractableNetworkIdentityAssetIDComparer : IEqualityComparer<IInteractable> { public bool Equals(IInteractable x, IInteractable y) { //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_0053: Unknown result type (might be due to invalid IL or missing references) if (x == null || y == null) { return false; } MonoBehaviour val = (MonoBehaviour)(object)((x is MonoBehaviour) ? x : null); MonoBehaviour val2 = (MonoBehaviour)(object)((y is MonoBehaviour) ? y : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { return false; } NetworkIdentity component = ((Component)val).GetComponent<NetworkIdentity>(); NetworkIdentity component2 = ((Component)val2).GetComponent<NetworkIdentity>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2)) { return false; } NetworkHash128 assetId = component.assetId; return ((NetworkHash128)(ref assetId)).Equals(component2.assetId); } public int GetHashCode(IInteractable obj) { return ((object)obj)?.GetHashCode() ?? (-1); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] public class FormatTokenAttribute : SearchableAttribute { public enum OperationTypeEnum { DivideByN, MultiplyByN, AddN, SubtractN, ModuloN } private object _cachedFormattingValue; public string languageToken { get; private set; } public OperationTypeEnum? operationType { get; private set; } public float? operationData { get; private set; } public int formattingIndex { get; private set; } internal object GetFormattingValue() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) object obj = null; if (((SearchableAttribute)this).target is FieldInfo fieldInfo) { obj = fieldInfo.GetValue(null); } else { if (!(((SearchableAttribute)this).target is PropertyInfo propertyInfo)) { throw new InvalidOperationException("FormatTokenAttribute is only valid in Fields and Properties"); } obj = propertyInfo.GetMethod?.Invoke(null, null); } Type type = obj.GetType(); if (type.IsSubclassOf(typeof(ConfiguredVariable))) { obj = ((ConfigEntryBase)(type.GetProperty("configEntryBase", BindingFlags.Instance | BindingFlags.Public).GetMethod?.Invoke(obj, null))).BoxedValue; } if (obj == null) { return string.Empty; } if (IsNumber(obj)) { if (operationType.HasValue && operationData.HasValue) { switch (operationType.Value) { case OperationTypeEnum.MultiplyByN: obj = MultiplyByN(CastToFloat(obj)); break; case OperationTypeEnum.DivideByN: obj = DivideByN(CastToFloat(obj)); break; case OperationTypeEnum.AddN: obj = AddN(CastToFloat(obj)); break; case OperationTypeEnum.ModuloN: obj = ModuloN(CastToFloat(obj)); break; case OperationTypeEnum.SubtractN: obj = SubtractN(CastToFloat(obj)); break; } } _cachedFormattingValue = obj; } else { _cachedFormattingValue = obj; } return _cachedFormattingValue; } private float CastToFloat(object obj) { return Convert.ToSingle(obj, CultureInfo.InvariantCulture); } private object MultiplyByN(float number) { float value = operationData.Value; return number * value; } private object DivideByN(float number) { float value = operationData.Value; return number / value; } private object AddN(float number) { float value = operationData.Value; return number + value; } private object SubtractN(float number) { return number - operationData; } private object ModuloN(float number) { float value = operationData.Value; return number % value; } private bool IsNumber(object value) { if (!(value is sbyte) && !(value is byte) && !(value is short) && !(value is ushort) && !(value is int) && !(value is uint) && !(value is long) && !(value is ulong) && !(value is float) && !(value is double)) { return value is decimal; } return true; } public FormatTokenAttribute(string token, int formattingIndex = 0) { languageToken = token; this.formattingIndex = formattingIndex; } public FormatTokenAttribute(string token, OperationTypeEnum opType, float opData, int formattingIndex = 0) { languageToken = token; operationType = opType; operationData = opData; this.formattingIndex = formattingIndex; } } internal static class FormatTokenManager { private static Dictionary<string, FormatTokenAttribute[]> _cachedFormattingArray; [SystemInitializer(new Type[] { typeof(ConfigSystem) })] private static IEnumerator Init() { MSULog.Info("Initializing FormatTokenManager", 21, "Init"); IEnumerator subroutine = CreateFormattingArray(); while (!subroutine.IsDone()) { yield return null; } foreach (Language allLanguage in Language.GetAllLanguages()) { AddTokensFromLanguageFileLoaderAndFormatThem(allLanguage); } Language.onCurrentLanguageChanged += Language_onCurrentLanguageChanged; ModOptionPanelController.OnModOptionsExit = (Action)Delegate.Combine(ModOptionPanelController.OnModOptionsExit, (Action)delegate { MSULog.Info("Reformatting Tokens.", 40, "Init"); AddTokensFromLanguageFileLoaderAndFormatThem(Language.currentLanguage); }); } private static void Language_onCurrentLanguageChanged() { MSULog.Info("Changed to language " + Language.currentLanguageName + ".", 48, "Language_onCurrentLanguageChanged"); AddTokensFromLanguageFileLoaderAndFormatThem(Language.currentLanguage); } private static void AddTokensFromLanguageFileLoaderAndFormatThem(Language currentLanguage) { string name = currentLanguage.name; if (!LanguageFileLoader._languageNameToRawTokenData.TryGetValue(name, out var value)) { return; } List<(string, string)> list = new List<(string, string)>(); foreach (var (text3, text4) in value) { if (_cachedFormattingArray.TryGetValue(text3, out var _)) { list.Add((text3, text4)); } else { currentLanguage.stringsByToken[text3] = text4; } } if (list.Count > 0) { ((MonoBehaviour)MSUMain.instance).StartCoroutine(FormatTokensWhenConfigsAreBound(currentLanguage, list)); } } private static IEnumerator FormatTokensWhenConfigsAreBound(Language target, List<(string, string)> tokenValuePair) { while (!ConfigSystem.configsBound) { yield return null; } foreach (var (text, text2) in tokenValuePair) { try { target.SetStringByToken(text, FormatString(text, text2, _cachedFormattingArray[text])); } catch (Exception arg) { MSULog.Error($"Failed to format string value for token {text} in language {target.name}. unformatted string will be used.\n{arg}", 100, "FormatTokensWhenConfigsAreBound"); target.SetStringByToken(text, text2); } } } private static IEnumerator CreateFormattingArray() { List<FormatTokenAttribute> propertyFormatTokens = new List<FormatTokenAttribute>(); List<FormatTokenAttribute> fieldFormatTokens = new List<FormatTokenAttribute>(); IEnumerator subroutine = GetFormatTokenLists(propertyFormatTokens, fieldFormatTokens); while (!subroutine.IsDone()) { yield return null; } Dictionary<string, FormatTokenAttribute[]> formattingDictionaryFromFields = new Dictionary<string, FormatTokenAttribute[]>(); Dictionary<string, FormatTokenAttribute[]> formattingDictionaryFromProperties = new Dictionary<string, FormatTokenAttribute[]>(); ParallelCoroutine parallelSubroutine = new ParallelCoroutine(); parallelSubroutine.Add(CreateFormattingDictionary(propertyFormatTokens, formattingDictionaryFromProperties)); parallelSubroutine.Add(CreateFormattingDictionary(fieldFormatTokens, formattingDictionaryFromFields)); while (!parallelSubroutine.IsDone()) { yield return null; } _cachedFormattingArray = new Dictionary<string, FormatTokenAttribute[]>(); string key; FormatTokenAttribute[] value; foreach (KeyValuePair<string, FormatTokenAttribute[]> item in formattingDictionaryFromFields) { item.Deconstruct(out key, out value); string token2 = key; FormatTokenAttribute[] formattingArray2 = value; yield return null; _cachedFormattingArray[token2] = Array.Empty<FormatTokenAttribute>(); FormatTokenAttribute[] arrayFromCache2 = _cachedFormattingArray[token2]; for (int j = 0; j < formattingArray2.Length; j++) { yield return null; if (arrayFromCache2.Length < j + 1) { Array.Resize(ref arrayFromCache2, j + 1); } if (arrayFromCache2[j] == null) { arrayFromCache2[j] = formattingArray2[j]; } } _cachedFormattingArray[token2] = arrayFromCache2; } foreach (KeyValuePair<string, FormatTokenAttribute[]> item2 in formattingDictionaryFromProperties) { item2.Deconstruct(out key, out value); string token2 = key; FormatTokenAttribute[] formattingArray2 = value; yield return null; if (!_cachedFormattingArray.ContainsKey(token2)) { _cachedFormattingArray[token2] = Array.Empty<FormatTokenAttribute>(); } FormatTokenAttribute[] arrayFromCache2 = _cachedFormattingArray[token2]; for (int j = 0; j < formattingArray2.Length; j++) { yield return null; if (arrayFromCache2.Length < j + 1) { Array.Resize(ref arrayFromCache2, j + 1); } if (arrayFromCache2[j] == null) { arrayFromCache2[j] = formattingArray2[j]; } } _cachedFormattingArray[token2] = arrayFromCache2; } } private static IEnumerator GetFormatTokenLists(List<FormatTokenAttribute> propertyFormatTokens, List<FormatTokenAttribute> fieldFormatTokens) { List<SearchableAttribute> source = SearchableAttribute.GetInstances<FormatTokenAttribute>() ?? new List<SearchableAttribute>(); foreach (FormatTokenAttribute formatToken in source.Cast<FormatTokenAttribute>()) { yield return null; if (((SearchableAttribute)formatToken).target is FieldInfo) { fieldFormatTokens.Add(formatToken); } else { propertyFormatTokens.Add(formatToken); } } } private static IEnumerator CreateFormattingDictionary(List<FormatTokenAttribute> source, Dictionary<string, FormatTokenAttribute[]> dest) { if (source.Count == 0) { yield break; } foreach (FormatTokenAttribute formatToken in source) { yield return null; try { string languageToken = formatToken.languageToken; int formattingIndex = formatToken.formattingIndex; if (!dest.ContainsKey(languageToken)) { dest[languageToken] = Array.Empty<FormatTokenAttribute>(); } FormatTokenAttribute[] array = dest[languageToken]; if (array.Length < formattingIndex + 1) { Array.Resize(ref array, formattingIndex + 1); } if (array[formattingIndex] == null) { array[formattingIndex] = formatToken; } dest[languageToken] = array; } catch (Exception data) { MSULog.Error(data, 225, "CreateFormattingDictionary"); } } } private static string FormatString(string token, string value, FormatTokenAttribute[] formattingArray) { object[] args = formattingArray.Select((FormatTokenAttribute att) => att.GetFormattingValue()).ToArray(); return string.Format(value, args); } } public enum GameplayEventIndex { None = -1 } public static class GameplayEventCatalog { public delegate void AddGameplayEventContentProviderDelegate(IGameplayEventContentProvider provider); public delegate void CollectGameplayEventContentProvidersDelegate(AddGameplayEventContentProviderDelegate addGameplayEventContentProvider); public interface IGameplayEventContentProvider { IEnumerator LoadGameplayEventsAsync(List<GameObject> dest); } private static GameObject[] _registeredGameplayEventObjects = Array.Empty<GameObject>(); private static GameplayEvent[] _registeredGameplayEventComponents = Array.Empty<GameplayEvent>(); private static readonly Dictionary<string, GameplayEventIndex> _nameToEventIndex = new Dictionary<string, GameplayEventIndex>(StringComparer.OrdinalIgnoreCase); public static ResourceAvailability catalogAvailability = default(ResourceAvailability); private static bool _initialized = false; public static int registeredGameplayEventCount => _registeredGameplayEventObjects.Length; public static event CollectGameplayEventContentProvidersDelegate collectGameplayEventContentProviders; public static GameplayEventIndex FindEventIndex(string eventName) { ThrowIfNotInitialized(); if (_nameToEventIndex.TryGetValue(eventName, out var value)) { return value; } return GameplayEventIndex.None; } public static GameObject GetGameplayEventObject(GameplayEventIndex index) { ThrowIfNotInitialized(); return ArrayUtils.GetSafe<GameObject>(_registeredGameplayEventObjects, (int)index); } public static GameplayEvent GetGameplayEvent(GameplayEventIndex index) { ThrowIfNotInitialized(); return ArrayUtils.GetSafe<GameplayEvent>(_registeredGameplayEventComponents, (int)index); } [SystemInitializer(new Type[] { })] private static IEnumerator Init() { MSULog.Info("Initializing the GameplayEvent Catalog...", 95, "Init"); List<IGameplayEventContentProvider> contentProviders = new List<IGameplayEventContentProvider>(); GameplayEventCatalog.collectGameplayEventContentProviders?.Invoke(AddGameplayEventContentProvider); List<GameObject> loadedEvents2 = new List<GameObject>(); ParallelCoroutine coroutine = new ParallelCoroutine(); foreach (IGameplayEventContentProvider contentProvider2 in contentProviders) { yield return null; coroutine.Add(contentProvider2.LoadGameplayEventsAsync(loadedEvents2)); } while (!coroutine.isDone) { yield return null; } _nameToEventIndex.Clear(); loadedEvents2 = loadedEvents2.OrderBy((GameObject go) => ((Object)go).name).ToList(); _registeredGameplayEventObjects = RegisterGameplayEvents(loadedEvents2).ToArray(); _registeredGameplayEventComponents = _registeredGameplayEventObjects.Select((GameObject g) => g.GetComponent<GameplayEvent>()).ToArray(); _initialized = true; ((ResourceAvailability)(ref catalogAvailability)).MakeAvailable(); void AddGameplayEventContentProvider(IGameplayEventContentProvider contentProvider) { contentProviders.Add(contentProvider); } } private static List<GameObject> RegisterGameplayEvents(List<GameObject> _gameplayEvents) { List<GameObject> list = new List<GameObject>(); for (int i = 0; i < _gameplayEvents.Count; i++) { try { EnsureValidity(_gameplayEvents[i], list); } catch (Exception data) { MSULog.Error(data, 139, "RegisterGameplayEvents"); } } for (int j = 0; j < list.Count; j++) { GameObject val = list[j]; GameplayEvent component = val.GetComponent<GameplayEvent>(); component.gameplayEventIndex = (GameplayEventIndex)j; _nameToEventIndex.Add(((Object)val).name, component.gameplayEventIndex); } return list; } private static void EnsureValidity(GameObject gameplayEvent, List<GameObject> validEvents) { GameplayEvent gameplayEvent2 = default(GameplayEvent); if (!gameplayEvent.TryGetComponent<GameplayEvent>(ref gameplayEvent2)) { throw new NullReferenceException($"GameObject {gameplayEvent} does not contain a GameplayEvent component."); } validEvents.Add(gameplayEvent); } private static void ThrowIfNotInitialized() { if (!_initialized) { throw new InvalidOperationException("GameplayEventCatalog not Initialized. Use \"catalogAvailability\" to call a method when the GameplayEventCatalog is initialized."); } } } public static class GameplayEventManager { public readonly struct GameplayEventSpawnArgs { public readonly GameObject gameplayEventPrefab; public readonly bool skipEventRequirementChecks; public readonly bool ignoreDuplicateEvents; public readonly bool doNotAnnounceStart; public readonly bool doNotAnnounceEnd; public readonly bool? beginOnStartOverride; public readonly float? expirationTimerOverride; public readonly float? announcementDurationOverride; public readonly EntityStateIndex? customTextStateIndex; public readonly GenericObjectIndex? customTMPFontAssetIndex; } public static bool GameplayEventExists(GameplayEvent gameplayEvent) { return GameplayEventExists(Object.op_Implicit((Object)(object)gameplayEvent) ? gameplayEvent.gameplayEventIndex : GameplayEventIndex.None); } public static bool GameplayEventExists(GameplayEventIndex index) { if (index == GameplayEventIndex.None) { return false; } foreach (GameplayEvent instances in InstanceTracker.GetInstancesList<GameplayEvent>()) { if (instances.gameplayEventIndex == index) { return true; } } return false; } public static bool GameplayEventIsPlaying(GameplayEvent gameplayEvent) { return GameplayEventIsPlaying(Object.op_Implicit((Object)(object)gameplayEvent) ? gameplayEvent.gameplayEventIndex : GameplayEventIndex.None); } public static bool GameplayEventIsPlaying(GameplayEventIndex index) { foreach (GameplayEvent instances in InstanceTracker.GetInstancesList<GameplayEvent>()) { if (instances.gameplayEventIndex == index) { return instances.isPlaying; } } return false; } public static GameplayEvent GetGameplayEventInstance(GameplayEvent prefabComponent) { return GetGameplayEventInstance(Object.op_Implicit((Object)(object)prefabComponent) ? prefabComponent.gameplayEventIndex : GameplayEventIndex.None); } public static GameplayEvent GetGameplayEventInstance(GameplayEventIndex index) { if (!GameplayEventExists(index)) { return null; } foreach (GameplayEvent instances in InstanceTracker.GetInstancesList<GameplayEvent>()) { if (instances.gameplayEventIndex == index) { return instances; } } return null; } public static bool AnyGameplayEventIsPlaying() { List<GameplayEvent> instancesList = InstanceTracker.GetInstancesList<GameplayEvent>(); if (instancesList.Count == 0) { return false; } foreach (GameplayEvent item in instancesList) { if (item.isPlaying) { return true; } } return false; } public static bool AnyGameplayEventExists() { return InstanceTracker.GetInstancesList<GameplayEvent>().Count > 0; } public static GameplayEvent SpawnGameplayEvent(GameplayEventSpawnArgs args) { if (!NetworkServer.active) { return null; } GameObject gameplayEventPrefab = args.gameplayEventPrefab; GameplayEvent gameplayEvent = default(GameplayEvent); if (gameplayEventPrefab.TryGetComponent<GameplayEvent>(ref gameplayEvent)) { return null; } if (gameplayEvent.gameplayEventIndex == GameplayEventIndex.None) { return null; } GameplayEventRequirement gameplayEventRequirement = default(GameplayEventRequirement); if (!args.skipEventRequirementChecks && gameplayEventPrefab.TryGetComponent<GameplayEventRequirement>(ref gameplayEventRequirement) && !gameplayEventRequirement.IsAvailable()) { return null; } if (!args.ignoreDuplicateEvents && GameplayEventExists(gameplayEvent.gameplayEventIndex)) { return null; } GameplayEvent component = Object.Instantiate<GameObject>(gameplayEventPrefab).GetComponent<GameplayEvent>(); if (args.beginOnStartOverride.HasValue) { component.NetworkbeginOnStart = args.beginOnStartOverride.Value; } if (args.expirationTimerOverride.HasValue) { component.eventDuration = args.expirationTimerOverride.Value; } if (args.announcementDurationOverride.HasValue) { component.announcementDuration = args.announcementDurationOverride.Value; } component.doNotAnnounceEnd = args.doNotAnnounceEnd; component.doNotAnnounceStart = args.doNotAnnounceStart; NetworkServer.Spawn(((Component)component).gameObject); return component; } } public static class GenericUnityObjectCatalog { public delegate void AddGenericObjectContentProviderDelegate(IGenericObjectContentProvider provider); public delegate void CollectGenericObjectContentProvidersDelegate(AddGenericObjectContentProviderDelegate addGameplayEventContentProvider); public interface IGenericObjectContentProvider { IEnumerator LoadGenericObjectsAsync(List<GenericObjectEntry> dest); } public struct GenericObjectEntry { public Object unityObject; private string _nameOverride; public string name { get { if (!Utility.IsNullOrWhiteSpace(_nameOverride)) { return _nameOverride; } return unityObject.name; } } public GenericObjectEntry(Object unityObject, string nameOverride = null) { _nameOverride = nameOverride; this.unityObject = unityObject; } } private static Object[] _registeredObjects = Array.Empty<Object>(); private static Dictionary<string, GenericObjectIndex> _nameToGenericObjectIndex = new Dictionary<string, GenericObjectIndex>(); public static ResourceAvailability catalogAvailability = default(ResourceAvailability); private static bool _initialized; public static int registeredObjectsCount => _registeredObjects.Length; public static event CollectGenericObjectContentProvidersDelegate collectGenericObjectContentProviders; public static GenericObjectIndex FindGenericObjectIndex(string name) { ThrowIfNotInitialized(); if (_nameToGenericObjectIndex.TryGetValue(name, out var value)) { return value; } return GenericObjectIndex.None; } public static T GetObject<T>(GenericObjectIndex index) where T : Object { ThrowIfNotInitialized(); Object safe = ArrayUtils.GetSafe<Object>(_registeredObjects, (int)index); if (Object.op_Implicit(safe)) { return (T)(object)safe; } return default(T); } public static Object GetObject(GenericObjectIndex index) { ThrowIfNotInitialized(); return ArrayUtils.GetSafe<Object>(_registeredObjects, (int)index); } [SystemInitializer(new Type[] { })] private static IEnumerator Init() { MSULog.Info("Initializing the GenericObject Catalog...", 86, "Init"); List<IGenericObjectContentProvider> contentProviders = new List<IGenericObjectContentProvider>(); GenericUnityObjectCatalog.collectGenericObjectContentProviders?.Invoke(AddGenericObjectContentProvider); List<GenericObjectEntry> loadedObjects2 = new List<GenericObjectEntry>(); ParallelCoroutine coroutine = new ParallelCoroutine(); foreach (IGenericObjectContentProvider contentProvider2 in contentProviders) { yield return null; coroutine.Add(contentProvider2.LoadGenericObjectsAsync(loadedObjects2)); } while (!coroutine.isDone) { yield return null; } _nameToGenericObjectIndex.Clear(); loadedObjects2 = loadedObjects2.OrderBy((GenericObjectEntry obj) => obj.name).ToList(); _registeredObjects = RegisterObjects(loadedObjects2).ToArray(); _initialized = true; ((ResourceAvailability)(ref catalogAvailability)).MakeAvailable(); void AddGenericObjectContentProvider(IGenericObjectContentProvider contentProvider) { contentProviders.Add(contentProvider); } } private static List<Object> RegisterObjects(List<GenericObjectEntry> entries) { List<GenericObjectEntry> list = new List<GenericObjectEntry>(); for (int i = 0; i < entries.Count; i++) { try { EnsureValidity(entries[i], list); } catch (Exception data) { MSULog.Error(data, 130, "RegisterObjects"); } } for (int j = 0; j < list.Count; j++) { GenericObjectEntry genericObjectEntry = list[j]; _nameToGenericObjectIndex.Add(genericObjectEntry.name, (GenericObjectIndex)j); } return list.Select((GenericObjectEntry goe) => goe.unityObject).ToList(); } private static void EnsureValidity(GenericObjectEntry entry, List<GenericObjectEntry> validEntries) { if (Utility.IsNullOrWhiteSpace(entry.name)) { throw new NullReferenceException("Entry's name is null"); } validEntries.Add(entry); } private static void ThrowIfNotInitialized() { if (!_initialized) { throw new InvalidOperationException("GenericObjectCatalog not Initialized. Use \"catalogAvailability\" to call a method when the GenericObjectCatalog is initialized."); } } } public enum GenericObjectIndex { None = -1 } internal static class ItemDisplayCatalog { private static StringComparer _comparer = StringComparer.OrdinalIgnoreCase; private static Dictionary<string, ItemDisplayRuleSet> _idrsDictionary = new Dictionary<string, ItemDisplayRuleSet>(_comparer); private static Dictionary<string, GameObject> _displayDictionary = new Dictionary<string, GameObject>(_comparer); public static ResourceAvailability catalogAvailability; public static GameObject GetItemDisplay(string key) { if (!_displayDictionary.ContainsKey(key)) { return null; } return _displayDictionary[key]; } public static ItemDisplayRuleSet GetItemDisplayRuleSet(string key) { if (!_idrsDictionary.ContainsKey(key)) { return null; } return _idrsDictionary[key]; } [SystemInitializer(new Type[] { })] private static IEnumerator SystemInitializer() { yield return null; RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate { MSULog.Info("Initializing the ItemDisplayCatalog...", 49, "SystemInitializer"); CreateIDRSDictionary(); CreateDisplayDictionary(); ((ResourceAvailability)(ref catalogAvailability)).MakeAvailable(); _idrsDictionary.Clear(); _displayDictionary.Clear(); }); } private static void CreateIDRSDictionary() { GameObject[] bodyPrefabs = BodyCatalog.bodyPrefabs; foreach (GameObject val in bodyPrefabs) { CharacterModel componentInChildren = val.GetComponentInChildren<CharacterModel>(); if (!Object.op_Implicit((Object)(object)componentInChildren)) { continue; } ItemDisplayRuleSet itemDisplayRuleSet = componentInChildren.itemDisplayRuleSet; if (Object.op_Implicit((Object)(object)itemDisplayRuleSet)) { string key = (Utility.IsNullOrWhiteSpace(((Object)itemDisplayRuleSet).name) ? ("idrs" + ((Object)val).name) : ((Object)itemDisplayRuleSet).name); if (!_idrsDictionary.ContainsKey(key)) { _idrsDictionary.Add(key, itemDisplayRuleSet); } } } } private static void CreateDisplayDictionary() { foreach (ItemDisplayRuleSet value3 in _idrsDictionary.Values) { PopulateDisplaysFromIDRS(value3); } foreach (KeyValuePair<ItemDef, IItemContentPiece> moonstormItem in ItemModule.moonstormItems) { moonstormItem.Deconstruct(out var _, out var value); PopulateDisplaysFromItems(value); } foreach (KeyValuePair<EquipmentDef, IEquipmentContentPiece> allMoonstormEquipment in EquipmentModule.allMoonstormEquipments) { allMoonstormEquipment.Deconstruct(out var _, out var value2); PopulateDisplaysFromEquips(value2); } } private static void PopulateDisplaysFromIDRS(ItemDisplayRuleSet idrs) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) KeyAssetRuleGroup[] keyAssetRuleGroups = idrs.keyAssetRuleGroups; foreach (KeyAssetRuleGroup val in keyAssetRuleGroups) { DisplayRuleGroup displayRuleGroup = val.displayRuleGroup; if (((DisplayRuleGroup)(ref displayRuleGroup)).isEmpty) { continue; } ItemDisplayRule[] rules = val.displayRuleGroup.rules; for (int j = 0; j < rules.Length; j++) { GameObject followerPrefab = rules[j].followerPrefab; if (!Object.op_Implicit((Object)(object)followerPrefab)) { continue; } string key = (Utility.IsNullOrWhiteSpace(((Object)followerPrefab).name) ? $"{val.keyAsset.name}Display_{j}" : ((Object)followerPrefab).name); if (!_displayDictionary.ContainsKey(key)) { _displayDictionary.Add(key, followerPrefab); } else if (!((Object)(object)_displayDictionary[key] == (Object)(object)followerPrefab)) { int num = j - 1;