using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("PlatinumCoin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PlatinumCoin")]
[assembly: AssemblyTitle("PlatinumCoin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace PlatinumCoin
{
[BepInPlugin("clippton.ultrakill.platinumcoin", "PlatinumCoin", "1.0.0")]
public sealed class Main : BaseUnityPlugin
{
public const string PluginGuid = "clippton.ultrakill.platinumcoin";
public const string PluginName = "PlatinumCoin";
public const string PluginVersion = "1.0.0";
internal static ConfigEntry<int> ProtectedHitCount;
private Harmony harmony;
private void Awake()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
ProtectedHitCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ProtectedHitCount", 3, "How many ricoshots a coin survives before being destroyed normally. Set to 0 for vanilla behavior.");
harmony = new Harmony("clippton.ultrakill.platinumcoin");
harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"PlatinumCoin 1.0.0 loaded.");
}
private void OnDestroy()
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
CoinProtection.Clear();
}
}
internal static class CoinProtection
{
private static readonly Dictionary<int, int> RemainingHits = new Dictionary<int, int>();
private static readonly FieldInfo ColsField = AccessTools.Field(typeof(Coin), "cols");
private static readonly FieldInfo ScolField = AccessTools.Field(typeof(Coin), "scol");
private static readonly FieldInfo CheckingSpeedField = AccessTools.Field(typeof(Coin), "checkingSpeed");
private static readonly FieldInfo TimeToDeleteField = AccessTools.Field(typeof(Coin), "timeToDelete");
private static readonly FieldInfo CurrentChargeField = AccessTools.Field(typeof(Coin), "currentCharge");
private static readonly FieldInfo AltBeamField = AccessTools.Field(typeof(Coin), "altBeam");
private static readonly FieldInfo PendingBeamHitsField = AccessTools.Field(typeof(Coin), "pendingBeamHits");
public static void Clear()
{
RemainingHits.Clear();
}
public static void Reset(Coin coin)
{
if ((Object)(object)coin != (Object)null)
{
RemainingHits.Remove(((Object)coin).GetInstanceID());
}
}
public static bool TryConsumeSave(Coin coin)
{
if ((Object)(object)coin == (Object)null)
{
return false;
}
int num = Mathf.Max(0, Main.ProtectedHitCount.Value);
if (num == 0)
{
Reset(coin);
return false;
}
int instanceID = ((Object)coin).GetInstanceID();
if (!RemainingHits.TryGetValue(instanceID, out var value))
{
value = num;
}
if (value <= 0)
{
return false;
}
RemainingHits[instanceID] = value - 1;
return true;
}
public static void ReviveAfterRicoshot(Coin coin)
{
//IL_0025: 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_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)coin == (Object)null)
{
return;
}
((Component)coin).gameObject.SetActive(true);
coin.shot = false;
coin.shotByEnemy = false;
coin.hitPoint = Vector3.zero;
coin.hitTimes = 1;
coin.ccc = null;
SetPrivateField(CheckingSpeedField, coin, true);
SetPrivateField(TimeToDeleteField, coin, 1f);
SetPrivateField(CurrentChargeField, coin, null);
SetPrivateField(AltBeamField, coin, null);
object value = PendingBeamHitsField.GetValue(coin);
(value?.GetType().GetMethod("Clear"))?.Invoke(value, null);
if (ColsField.GetValue(coin) is Collider[] array)
{
Collider[] array2 = array;
foreach (Collider val in array2)
{
if ((Object)(object)val != (Object)null)
{
val.enabled = true;
}
}
}
object? value2 = ScolField.GetValue(coin);
SphereCollider val2 = (SphereCollider)((value2 is SphereCollider) ? value2 : null);
if ((Object)(object)val2 != (Object)null)
{
((Collider)val2).enabled = true;
val2.radius = 0.5f;
}
if ((Object)(object)coin.rb != (Object)null)
{
coin.rb.isKinematic = false;
coin.rb.velocity = Vector3.up * 8f;
coin.rb.angularVelocity = Random.insideUnitSphere * 20f;
PhysicsExtensions.SetGravityMode(coin.rb, true);
}
TrailRenderer component = ((Component)coin).GetComponent<TrailRenderer>();
if ((Object)(object)component != (Object)null)
{
component.Clear();
((Renderer)component).enabled = true;
}
((MonoBehaviour)coin).CancelInvoke("ReflectRevolver");
((MonoBehaviour)coin).CancelInvoke("GetDeleted");
((MonoBehaviour)coin).Invoke("GetDeleted", 5f);
MonoSingleton<CoinTracker>.Instance.AddCoin(coin);
}
private static void SetPrivateField(FieldInfo field, object instance, object value)
{
if (field != null)
{
field.SetValue(instance, value);
}
}
}
[HarmonyPatch(typeof(Coin))]
internal static class CoinPatches
{
[HarmonyPostfix]
[HarmonyPatch("Start")]
private static void StartPostfix(Coin __instance)
{
CoinProtection.Reset(__instance);
}
[HarmonyPostfix]
[HarmonyPatch("ReflectRevolver")]
private static void ReflectRevolverPostfix(Coin __instance)
{
if (!((Object)(object)__instance == (Object)null) && !((Component)__instance).gameObject.activeSelf && CoinProtection.TryConsumeSave(__instance))
{
CoinProtection.ReviveAfterRicoshot(__instance);
}
}
[HarmonyPrefix]
[HarmonyPatch("GetDeleted")]
private static void GetDeletedPrefix(Coin __instance)
{
CoinProtection.Reset(__instance);
}
}
}