using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using HG; using JetBrains.Annotations; using UnityEngine; using UnityEngine.Networking; namespace RoR2; [RequireComponent(typeof(Run))] [DisallowMultipleComponent] public class RunArtifactManager : NetworkBehaviour { public delegate void ArtifactStateChangeDelegate([NotNull] RunArtifactManager runArtifactManager, [NotNull] ArtifactDef artifactDef); public struct RunEnabledArtifacts : IEnumerator, IEnumerator, IDisposable { private ArtifactIndex artifactIndex; public ArtifactDef Current => ArtifactCatalog.GetArtifactDef(artifactIndex); object IEnumerator.Current => Current; public bool MoveNext() { RunArtifactManager instance = RunArtifactManager.instance; if ((object)instance == null) { return false; } while ((int)(++artifactIndex) < ArtifactCatalog.artifactCount) { if (instance.IsArtifactEnabled(artifactIndex)) { return true; } } return false; } public void Reset() { artifactIndex = ArtifactIndex.None; } public void Dispose() { } } private Run run; private static readonly uint enabledArtifactsDirtyBit = 1u; private static readonly uint allDirtyBits = enabledArtifactsDirtyBit; private bool[] _enabledArtifacts; private static readonly FixedSizeArrayPool enabledArtifactMaskPool = new FixedSizeArrayPool(0); public static readonly GenericStaticEnumerable enabledArtifactsEnumerable = default(GenericStaticEnumerable); public static RunArtifactManager instance { get; private set; } public static event ArtifactStateChangeDelegate onArtifactEnabledGlobal; public static event ArtifactStateChangeDelegate onArtifactDisabledGlobal; private void Awake() { _enabledArtifacts = enabledArtifactMaskPool.Request(); run = GetComponent(); Run.onServerRunSetRuleBookGlobal += OnServerRunSetRuleBook; } private void OnDestroy() { int i = 0; for (int artifactCount = ArtifactCatalog.artifactCount; i < artifactCount; i++) { SetArtifactEnabled(ArtifactCatalog.GetArtifactDef((ArtifactIndex)i), newEnabled: false); } Run.onServerRunSetRuleBookGlobal -= OnServerRunSetRuleBook; if (_enabledArtifacts != null) { enabledArtifactMaskPool.Return(_enabledArtifacts); _enabledArtifacts = null; } } private void OnEnable() { instance = SingletonHelper.Assign(instance, this); } private void OnDisable() { instance = SingletonHelper.Unassign(instance, this); } public override bool OnSerialize(NetworkWriter writer, bool initialState) { uint num = (initialState ? allDirtyBits : base.syncVarDirtyBits); bool num2 = (num & enabledArtifactsDirtyBit) != 0; writer.WritePackedUInt32(num); if (num2) { writer.WriteBitArray(_enabledArtifacts); } if (!initialState) { return num != 0; } return false; } public override void OnDeserialize(NetworkReader reader, bool initialState) { if ((reader.ReadPackedUInt32() & enabledArtifactsDirtyBit) != 0) { bool[] array = enabledArtifactMaskPool.Request(); reader.ReadBitArray(array); int i = 0; for (int artifactCount = ArtifactCatalog.artifactCount; i < artifactCount; i++) { SetArtifactEnabled(ArtifactCatalog.GetArtifactDef((ArtifactIndex)i), array[i]); } } } private void OnServerRunSetRuleBook([NotNull] Run run, [NotNull] RuleBook newRuleBook) { bool[] array = enabledArtifactMaskPool.Request(); int i = 0; for (int ruleCount = RuleCatalog.ruleCount; i < ruleCount; i++) { RuleChoiceDef ruleChoice = newRuleBook.GetRuleChoice(i); if (ruleChoice.artifactIndex != ArtifactIndex.None) { array[(int)ruleChoice.artifactIndex] = true; } } int j = 0; for (int artifactCount = ArtifactCatalog.artifactCount; j < artifactCount; j++) { SetArtifactEnabled(ArtifactCatalog.GetArtifactDef((ArtifactIndex)j), array[j]); } enabledArtifactMaskPool.Return(array); } private void SetArtifactEnabled([NotNull] ArtifactDef artifactDef, bool newEnabled) { ref bool reference = ref _enabledArtifacts[(int)artifactDef.artifactIndex]; if (reference != newEnabled) { if (NetworkServer.active) { SetDirtyBit(enabledArtifactsDirtyBit); } reference = newEnabled; (reference ? RunArtifactManager.onArtifactEnabledGlobal : RunArtifactManager.onArtifactDisabledGlobal)?.Invoke(this, artifactDef); } } [SystemInitializer(new Type[] { typeof(ArtifactCatalog) })] private static void Init() { enabledArtifactMaskPool.lengthOfArrays = ArtifactCatalog.artifactCount; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsArtifactEnabled([NotNull] ArtifactDef artifactDef) { return IsArtifactEnabled(artifactDef.artifactIndex); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsArtifactEnabled(ArtifactIndex artifactIndex) { bool[] enabledArtifacts = _enabledArtifacts; bool defaultValue = false; return ArrayUtils.GetSafe(enabledArtifacts, (int)artifactIndex, in defaultValue); } [Server] public void SetArtifactEnabledServer(ArtifactDef artifactDef, bool newEnabled) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.RunArtifactManager::SetArtifactEnabledServer(RoR2.ArtifactDef,System.Boolean)' called on client"); } else { SetArtifactEnabled(artifactDef, newEnabled); } } private void UNetVersion() { } public override void PreStartClient() { } }