Decompiled source of Payback v1.0.0

plugins/PaybackMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModdingUtils.Utils;
using Nullmanager;
using RarityLib.Utils;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("PaybackMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PaybackMod")]
[assembly: AssemblyTitle("PaybackMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 PaybackMod
{
	public class PaybackCard : CustomCard
	{
		private static GameObject _cachedArt;

		public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
		{
			cardInfo.cardName = "PAYBACK";
			cardInfo.cardDestription = "";
		}

		public override void OnAddCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
			if ((Object)(object)((Component)player).gameObject.GetComponent<PaybackEffect>() == (Object)null)
			{
				((Component)player).gameObject.AddComponent<PaybackEffect>();
			}
			PaybackPlugin.Log.LogInfo((object)$"[Payback] Card added to player {player.playerID}");
		}

		public override void OnRemoveCard(Player player, Gun gun, GunAmmo gunAmmo, CharacterData data, HealthHandler health, Gravity gravity, Block block, CharacterStatModifiers characterStats)
		{
		}

		protected override string GetTitle()
		{
			return "PAYBACK";
		}

		protected override string GetDescription()
		{
			return "";
		}

		protected override CardInfoStat[] GetStats()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0034: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0060: 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)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_008a: Expected O, but got Unknown
			return (CardInfoStat[])(object)new CardInfoStat[3]
			{
				new CardInfoStat
				{
					positive = true,
					stat = "Nulls",
					amount = "+50",
					simepleAmount = (SimpleAmount)0
				},
				new CardInfoStat
				{
					positive = true,
					stat = "On Death",
					amount = "Copy a card",
					simepleAmount = (SimpleAmount)0
				},
				new CardInfoStat
				{
					positive = true,
					stat = "Stacks",
					amount = "Forever",
					simepleAmount = (SimpleAmount)0
				}
			};
		}

		protected override Rarity GetRarity()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return RarityUtils.GetRarity("Legendary");
		}

		protected override GameObject GetCardArt()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_cachedArt != (Object)null)
			{
				return _cachedArt;
			}
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				using Stream stream = executingAssembly.GetManifestResourceStream("PaybackMod.Assets.PaybackIcon.png");
				if (stream == null)
				{
					PaybackPlugin.Log.LogWarning((object)"[Payback] PaybackIcon.png not found in embedded resources");
					return null;
				}
				byte[] array;
				using (MemoryStream memoryStream = new MemoryStream())
				{
					stream.CopyTo(memoryStream);
					array = memoryStream.ToArray();
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				ImageConversion.LoadImage(val, array);
				((Texture)val).filterMode = (FilterMode)1;
				Sprite sprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				GameObject val2 = new GameObject("PaybackArt", new Type[1] { typeof(RectTransform) });
				Object.DontDestroyOnLoad((Object)(object)val2);
				Image val3 = val2.AddComponent<Image>();
				val3.sprite = sprite;
				val3.preserveAspect = true;
				RectTransform component = val2.GetComponent<RectTransform>();
				component.sizeDelta = new Vector2(900f, 900f);
				_cachedArt = val2;
				return _cachedArt;
			}
			catch (Exception arg)
			{
				PaybackPlugin.Log.LogError((object)$"[Payback] Card art load failed: {arg}");
				return null;
			}
		}

		protected override CardThemeColorType GetTheme()
		{
			return (CardThemeColorType)0;
		}
	}
	public class PaybackEffect : MonoBehaviour
	{
		private Player owner;

		private CharacterData ownerData;

		private bool registered = false;

		private float lastKnownHealth = -1f;

		private Player lastSeenAttacker = null;

		private void Start()
		{
			owner = ((Component)this).GetComponent<Player>();
			ownerData = ((Component)this).GetComponent<CharacterData>();
			try
			{
				CharacterStatModifiersExtension.AjustNulls(owner.data.stats, 50);
				PaybackPlugin.Log.LogInfo((object)$"[Payback] Gave 50 nulls to player {owner.playerID}");
			}
			catch (Exception ex)
			{
				PaybackPlugin.Log.LogWarning((object)("[Payback] Failed to add nulls: " + ex.Message));
			}
			if (!registered)
			{
				GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)OnRoundEnd);
				registered = true;
				PaybackPlugin.Log.LogInfo((object)$"[Payback] Registered RoundEnd hook for player {owner.playerID}");
			}
		}

		private void OnDestroy()
		{
			if (registered)
			{
				GameModeManager.RemoveHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)OnRoundEnd);
			}
		}

		private void Update()
		{
			if ((Object)(object)ownerData == (Object)null)
			{
				return;
			}
			if (lastKnownHealth < 0f)
			{
				lastKnownHealth = ownerData.health;
				return;
			}
			if (ownerData.health < lastKnownHealth)
			{
				Player val = TryGetPlayerFromObject(ownerData.lastSourceOfDamage) ?? ownerData.lastDamagedPlayer;
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)owner)
				{
					lastSeenAttacker = val;
					PaybackPlugin.Log.LogInfo((object)($"[Payback] Player {owner.playerID} took damage from player {val.playerID} " + $"(health {lastKnownHealth:F1} -> {ownerData.health:F1})"));
				}
			}
			lastKnownHealth = ownerData.health;
		}

		private Player TryGetPlayerFromObject(object obj)
		{
			if (obj == null)
			{
				return null;
			}
			Player val = (Player)((obj is Player) ? obj : null);
			if (val != null)
			{
				return val;
			}
			Component val2 = (Component)((obj is Component) ? obj : null);
			if (val2 != null)
			{
				return val2.GetComponent<Player>() ?? val2.GetComponentInParent<Player>();
			}
			GameObject val3 = (GameObject)((obj is GameObject) ? obj : null);
			if (val3 != null)
			{
				return val3.GetComponent<Player>() ?? val3.GetComponentInParent<Player>();
			}
			return null;
		}

		private IEnumerator OnRoundEnd(IGameModeHandler gm)
		{
			if (!ownerData.dead)
			{
				PaybackPlugin.Log.LogInfo((object)$"[Payback] Player {owner.playerID} survived the round — no copy.");
				ResetRound();
				yield break;
			}
			Player killer = lastSeenAttacker;
			if ((Object)(object)killer == (Object)null || (Object)(object)killer == (Object)(object)owner)
			{
				PaybackPlugin.Log.LogWarning((object)$"[Payback] Player {owner.playerID} died but no killer tracked.");
				ResetRound();
				yield break;
			}
			CardInfo cardToCopy = PickRandomCard(killer);
			if ((Object)(object)cardToCopy == (Object)null)
			{
				PaybackPlugin.Log.LogWarning((object)$"[Payback] Killer player {killer.playerID} has no cards to copy.");
				ResetRound();
			}
			else if ((Object)(object)cardToCopy == (Object)(object)PaybackPlugin.PaybackCardInfo || cardToCopy.cardName == "PAYBACK")
			{
				PaybackPlugin.Log.LogInfo((object)"[Payback] Copied Payback itself! Removing 15 nulls.");
				try
				{
					CharacterStatModifiersExtension.AjustNulls(owner.data.stats, -15);
				}
				catch (Exception ex)
				{
					Exception e = ex;
					PaybackPlugin.Log.LogWarning((object)("[Payback] Failed to remove nulls: " + e.Message));
				}
				PaybackPopup.Show("PAYBACK COPIED — -15 NULLS");
				ResetRound();
			}
			else
			{
				PaybackPlugin.Log.LogInfo((object)($"[Payback] Round ended. Player {owner.playerID} copying '{cardToCopy.cardName}' " + $"from player {killer.playerID}"));
				try
				{
					Cards.instance.AddCardToPlayer(owner, cardToCopy, false, "", 0f, 1f, true);
					PaybackPlugin.Log.LogInfo((object)"[Payback] Card copy succeeded!");
				}
				catch (Exception ex)
				{
					Exception e2 = ex;
					PaybackPlugin.Log.LogError((object)("[Payback] Failed to add card: " + e2.Message));
				}
				ResetRound();
			}
		}

		private void ResetRound()
		{
			lastSeenAttacker = null;
			lastKnownHealth = -1f;
		}

		private static CardInfo PickRandomCard(Player killer)
		{
			List<CardInfo> currentCards = killer.data.currentCards;
			if (currentCards == null || currentCards.Count == 0)
			{
				return null;
			}
			return currentCards[Random.Range(0, currentCards.Count)];
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.itay.rounds.payback", "Payback", "1.0.0")]
	[BepInProcess("Rounds.exe")]
	public class PaybackPlugin : BaseUnityPlugin
	{
		private const string ModId = "com.itay.rounds.payback";

		private const string ModName = "Payback";

		private const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static CardInfo PaybackCardInfo;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			harmony = new Harmony("com.itay.rounds.payback");
			harmony.PatchAll();
			CustomCard.BuildCard<PaybackCard>((Action<CardInfo>)delegate(CardInfo cardInfo)
			{
				PaybackCardInfo = cardInfo;
			});
			Log.LogInfo((object)"[Payback] Mod loaded.");
		}

		private void Update()
		{
			if ((Object)(object)PaybackCardInfo == (Object)null)
			{
				return;
			}
			Player[] array = PlayerManager.instance?.players?.ToArray();
			if (array == null || array.Length == 0)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)286))
			{
				Player[] array2 = array;
				foreach (Player val in array2)
				{
					Cards.instance.AddCardToPlayer(val, PaybackCardInfo, false, "", 0f, 1f, true);
					Log.LogInfo((object)$"[Payback] [F5] Gave Payback card to player {val.playerID}");
				}
			}
			if (Input.GetKeyDown((KeyCode)287))
			{
				Player val2 = array[0];
				Cards.instance.AddCardToPlayer(val2, PaybackCardInfo, false, "", 0f, 1f, true);
				Log.LogInfo((object)$"[Payback] [F6] Gave Payback card to player {val2.playerID}");
			}
		}
	}
	public static class PaybackPopup
	{
		public static void Show(string text)
		{
			try
			{
				Unbound.BuildInfoPopup(text);
			}
			catch (Exception ex)
			{
				PaybackPlugin.Log.LogWarning((object)("[Payback] Popup failed: " + ex.Message));
			}
		}
	}
}