using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Crossover")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bde1bfeb7ae7cc5ed6b76bb8e48c2a27ed934b99")]
[assembly: AssemblyProduct("Crossover")]
[assembly: AssemblyTitle("Crossover")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 Crossover
{
public class ConfigManager
{
public static PluginConfigurator config;
public static BoolField Enable;
public static ColorField AccentColor;
public static FloatField StartScale;
public static FloatField EndScale;
public static FloatField EnemyHealthThreshold;
public static FloatSliderField CrossMarkOpacity;
public static void Initialize()
{
}
static ConfigManager()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Expected O, but got Unknown
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Expected O, but got Unknown
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Expected O, but got Unknown
config = PluginConfigurator.Create("Crossover", "com.github.end-4.crossover");
string text = Path.Combine(Plugin.workingDir, "icon.png");
if (File.Exists(text))
{
config.SetIconWithURL(text);
}
new ConfigHeader(config.rootPanel, "", 10);
Enable = new BoolField(config.rootPanel, "Enable death crosses", "enable", true);
AccentColor = new ColorField(config.rootPanel, "Cross accent color", "accentColor", new Color(73f / 85f, 0.11764706f, 19f / 85f));
StartScale = new FloatField(config.rootPanel, "Cross starting scale", "startScale", 2f);
EndScale = new FloatField(config.rootPanel, "Cross ending scale", "endScale", 0.35f);
EnemyHealthThreshold = new FloatField(config.rootPanel, "Enemy health threshold", "enemyHealthThreshold", 0f);
CrossMarkOpacity = new FloatSliderField(config.rootPanel, "Cross mark opacity", "crossMarkOpacity", new Tuple<float, float>(0f, 1f), 1f);
}
}
public class CrossBehavior : MonoBehaviour
{
private enum State
{
Hidden,
Marking
}
public float markLifetime = 0.4f;
public float scalingDuration = 0.1333f;
public float startScale = 1f;
public float endScale = 0.2f;
public Tuple<float, Color>[] colorSteps = new Tuple<float, Color>[5]
{
Tuple.Create<float, Color>(0f, Color.white),
Tuple.Create<float, Color>(0.0333f, Color.black),
Tuple.Create<float, Color>(0.0667f, Color.white),
Tuple.Create<float, Color>(0.1333f, Color.black),
Tuple.Create<float, Color>(0.2f, Color.red)
};
public EnemyIdentifier enemy;
private CanvasGroup canvasGroup;
private float enemyHeight;
private RectTransform rectTransform;
private Image frontLayerImage;
private State state;
private float startMarkTime;
private Vector3 targetPoint;
private Vector3 lastEnemyPosition = Vector3.zero;
private float scaleDiff => startScale - endScale;
private void Awake()
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
canvasGroup = ((Component)this).GetComponent<CanvasGroup>();
frontLayerImage = ((Component)((Component)this).transform.Find("DeathCrossFrontLayer")).gameObject.GetComponent<Image>();
Image component = ((Component)this).gameObject.GetComponent<Image>();
((Graphic)component).color = ConfigManager.AccentColor.value;
colorSteps[^1] = Tuple.Create<float, Color>(colorSteps[^1].Item1, ((Graphic)component).color);
startScale = ConfigManager.StartScale.value;
endScale = ConfigManager.EndScale.value;
}
private void Start()
{
//IL_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
ref RectTransform reference = ref rectTransform;
Transform transform = ((Component)this).transform;
reference = (RectTransform)(object)((transform is RectTransform) ? transform : null);
Collider component = ((Component)enemy).GetComponent<Collider>();
Bounds bounds = component.bounds;
float y = (((Bounds)(ref bounds)).center - ((Component)enemy).transform.position).y;
bounds = component.bounds;
enemyHeight = y + ((Bounds)(ref bounds)).extents.y;
}
private float Curve(float x)
{
float num = Math.Clamp(x, 0f, 1f);
float num2 = 1f - num;
return 1f - num2 * num2 * num2;
}
private Vector3 GetMarkPosition()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)enemy != (Object)null && (Object)(object)((Component)enemy).transform != (Object)null)
{
lastEnemyPosition = ((Component)enemy).transform.position;
}
return lastEnemyPosition + enemyHeight / 2f * Vector3.up;
}
private void UpdateTargetPoint()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: 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_008e: Unknown result type (might be due to invalid IL or missing references)
targetPoint = MonoSingleton<CameraController>.Instance.cam.WorldToScreenPoint(GetMarkPosition());
int privateField = MonoSingleton<PostProcessV2_Handler>.Instance.GetPrivateField<int>("width");
int privateField2 = MonoSingleton<PostProcessV2_Handler>.Instance.GetPrivateField<int>("height");
targetPoint.x *= Screen.width;
targetPoint.y *= Screen.height;
targetPoint.x /= privateField;
targetPoint.y /= privateField2;
((Transform)rectTransform).position = targetPoint;
}
private void UpdateColor(float elapsedTime)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
int i = 0;
if (!(elapsedTime < 0f))
{
for (; i < colorSteps.Length && elapsedTime >= colorSteps[i].Item1; i++)
{
}
((Graphic)frontLayerImage).color = colorSteps[i - 1].Item2;
}
}
private void SetScale(float newScale)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
((Transform)rectTransform).localScale = new Vector3(newScale, newScale, newScale);
}
private void UpdateScale(float percentage)
{
float scale = startScale - Curve(percentage) * scaleDiff;
SetScale(scale);
}
private void Update()
{
if (state == State.Hidden && ((Object)(object)enemy == (Object)null || enemy.health <= 0f))
{
state = State.Marking;
startMarkTime = Time.time;
canvasGroup.alpha = ConfigManager.CrossMarkOpacity.value;
}
if (state != 0)
{
float num = Time.time - startMarkTime;
UpdateColor(num);
UpdateScale(num / scalingDuration);
UpdateTargetPoint();
if (Time.time - startMarkTime >= markLifetime)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
}
}
[BepInPlugin("com.github.end-4.crossover", "Crossover", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource? Log;
public static string workingPath = Assembly.GetExecutingAssembly().Location;
public static string workingDir = Path.GetDirectoryName(workingPath);
public const string PluginGUID = "com.github.end-4.crossover";
public const string PluginName = "Crossover";
public const string PluginVersion = "1.0.0";
internal static GameObject DeathCrossPrefab;
internal static GameObject DeathCrossCanvasPrefab;
internal static GameObject DeathCrossCanvas;
private static readonly string BundlePath = Path.Combine(workingDir, "assets", "crossover.bundle");
private void LoadObjects()
{
AssetBundle obj = AssetBundle.LoadFromFile(BundlePath);
if ((Object)(object)obj == (Object)null)
{
Log.LogError((object)"Couldn't load asset bundle");
}
DeathCrossPrefab = obj.LoadAsset<GameObject>("DeathCross");
DeathCrossCanvasPrefab = obj.LoadAsset<GameObject>("DeathCrossCanvas");
DeathCrossCanvas = Object.Instantiate<GameObject>(DeathCrossCanvasPrefab);
Object.DontDestroyOnLoad((Object)(object)DeathCrossCanvas);
((Object)DeathCrossCanvas).hideFlags = (HideFlags)61;
}
private void Awake()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
ConfigManager.Initialize();
LoadObjects();
new Harmony("Crossover").PatchAll();
Log.LogInfo((object)"Crossover loaded!");
}
}
internal static class Utils
{
public static T GetPrivateField<T>(this object obj, string field)
{
Type type = obj.GetType();
if (type.GetField(field, BindingFlags.Instance | BindingFlags.NonPublic) == null)
{
throw new ArgumentException("The field " + field + " does not exist in target class " + type.Name + "!");
}
return (T)type.GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
}
}
}
namespace Crossover.Patches
{
[HarmonyPatch(typeof(EnemyIdentifier))]
public class EnemyPatch
{
[HarmonyPostfix]
[HarmonyPatch("Start")]
public static void EnemySpawned(EnemyIdentifier __instance)
{
if (ConfigManager.Enable.value && !(__instance.health < ConfigManager.EnemyHealthThreshold.value))
{
GameObject obj = Object.Instantiate<GameObject>(Plugin.DeathCrossPrefab, Plugin.DeathCrossCanvas.transform);
obj.GetComponent<CanvasGroup>().alpha = 0f;
obj.AddComponent<CrossBehavior>().enemy = __instance;
}
}
}
}