Decompiled source of CustomCardSacrificeCost v1.0.0

GeckVolantMarin-CustomCardSacrificeCost.dll

Decompiled 20 hours ago
using System;
using System.Collections;
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.Logging;
using DiskCardGame;
using HarmonyLib;
using InscryptionAPI.Card;
using InscryptionAPI.CardCosts;
using InscryptionAPI.Helpers;
using InscryptionAPI.Helpers.Extensions;
using InscryptionCommunityPatch.Card;
using InscryptionCommunityPatch.ResourceManagers;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GeckVolantMarin-CustomCardSacrificeCost")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GeckVolantMarin-CustomCardSacrificeCost")]
[assembly: AssemblyTitle("GeckVolantMarin-CustomCardSacrificeCost")]
[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 GeckVolantMarin
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "GeckVolantMarin-CustomCardSacrificeCost";

		public const string PLUGIN_NAME = "GeckVolantMarin-CustomCardSacrificeCost";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace GeckVolantMarin.CustomCardSacrificeCost
{
	public abstract class CustomSacrificeCost : CustomCardCost
	{
		public abstract int satisfiesSacrifices(PlayableCard card);
	}
	[HarmonyPatch]
	public class CustomSacrificeCostPatch
	{
		public class CostAndValidSlots
		{
			public CustomSacrificeCost customSacrificeCost;

			public List<CardSlot> validSlots;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public class PlayCardOnSlot
		{
			[HarmonyPrefix]
			public static bool Prefix(PlayerHand __instance, PlayableCard card, out bool __state)
			{
				__state = CardExtensions.GetCustomCardCosts((Card)(object)card).Count > 0;
				return CardExtensions.GetCustomCardCosts((Card)(object)card).Count == 0;
			}

			[HarmonyPostfix]
			public static IEnumerator Postfix(IEnumerator enumerator, PlayerHand __instance, PlayableCard card, bool __state)
			{
				if (__state)
				{
					__instance.CardsInHand.ForEach(delegate(PlayableCard x)
					{
						((InteractableBase)x).SetEnabled(false);
					});
					yield return (object)new WaitWhile((Func<bool>)(() => __instance.ChoosingSlot));
					__instance.OnSelectSlotStartedForCard(card);
					if ((Object)(object)Singleton<RuleBookController>.Instance != (Object)null)
					{
						Singleton<RuleBookController>.Instance.SetShown(false, true);
					}
					Singleton<BoardManager>.Instance.CancelledSacrifice = false;
					__instance.choosingSlotCard = card;
					if ((Object)(object)card != (Object)null && (Object)(object)((Card)card).Anim != (Object)null)
					{
						((Card)card).Anim.SetSelectedToPlay(true);
					}
					Singleton<BoardManager>.Instance.ShowCardNearBoard(card, true);
					if ((Object)(object)Singleton<TurnManager>.Instance.SpecialSequencer != (Object)null)
					{
						yield return Singleton<TurnManager>.Instance.SpecialSequencer.CardSelectedFromHand(card);
					}
					bool cardWasPlayed = false;
					bool requiresSacrifices = true;
					if (requiresSacrifices)
					{
						Plugin.Logger.LogInfo((object)"This card has CustomSacrificeCosts.");
						List<CostAndValidSlots> listCostAndValidSlots = new List<CostAndValidSlots>();
						foreach (CustomCardCost cardCostIt in CardExtensions.GetCustomCardCosts((Card)(object)card))
						{
							if (!(cardCostIt is CustomSacrificeCost))
							{
								continue;
							}
							Plugin.Logger.LogInfo((object)("\tOne of them was " + cardCostIt.CostName + "."));
							CostAndValidSlots toAddCostAndValidSlots = new CostAndValidSlots
							{
								customSacrificeCost = (cardCostIt as CustomSacrificeCost),
								validSlots = new List<CardSlot>()
							};
							Plugin.Logger.LogInfo((object)"\t\tHere is a list of valid card on board for this cost:");
							foreach (PlayableCard cardIt2 in BoardManagerExtensions.GetPlayerCards(Singleton<BoardManager>.Instance, (Predicate<PlayableCard>)null))
							{
								if (toAddCostAndValidSlots.customSacrificeCost.satisfiesSacrifices(cardIt2) > 0)
								{
									Plugin.Logger.LogInfo((object)("\t\t\t- " + ((Card)cardIt2).Info.displayedName + " on Slot.Index " + cardIt2.Slot.Index + "."));
									toAddCostAndValidSlots.validSlots.Add(cardIt2.Slot);
								}
							}
							listCostAndValidSlots.Add(toAddCostAndValidSlots);
						}
						if (CardExtensions.BloodCost(card) > 0)
						{
							Plugin.Logger.LogInfo((object)("\tAlso, the card cost" + CardExtensions.BloodCost(card) + " blood."));
							CostAndValidSlots toAddCostAndValidSlots2 = new CostAndValidSlots
							{
								customSacrificeCost = null,
								validSlots = new List<CardSlot>()
							};
							Plugin.Logger.LogInfo((object)"\t\tHere is a list of valid card on board for blood sacrifice:");
							foreach (PlayableCard cardIt in BoardManagerExtensions.GetPlayerCards(Singleton<BoardManager>.Instance, (Predicate<PlayableCard>)null))
							{
								if (((Card)cardIt).Info.Sacrificable)
								{
									Plugin.Logger.LogInfo((object)("\t\t\t- " + ((Card)cardIt).Info.displayedName + " on Slot.Index " + cardIt.Slot.Index + "."));
									toAddCostAndValidSlots2.validSlots.Add(cardIt.Slot);
								}
							}
							listCostAndValidSlots.Add(toAddCostAndValidSlots2);
						}
						yield return ChooseSacrificesForCard(listCostAndValidSlots, card);
					}
					if (!Singleton<BoardManager>.Instance.CancelledSacrifice)
					{
						List<CardSlot> validSlots2 = Singleton<BoardManager>.Instance.PlayerSlotsCopy.FindAll((CardSlot x) => (Object)(object)x.Card == (Object)null);
						yield return Singleton<BoardManager>.Instance.ChooseSlot(validSlots2, !requiresSacrifices);
						CardSlot lastSelectedSlot = Singleton<BoardManager>.Instance.LastSelectedSlot;
						if ((Object)(object)lastSelectedSlot != (Object)null)
						{
							cardWasPlayed = true;
							((Card)card).Anim.SetSelectedToPlay(false);
							yield return __instance.PlayCardOnSlot(card, lastSelectedSlot);
							if (((Card)card).Info.BonesCost > 0)
							{
								yield return Singleton<ResourcesManager>.Instance.SpendBones(((Card)card).Info.BonesCost);
							}
							if (card.EnergyCost > 0)
							{
								yield return Singleton<ResourcesManager>.Instance.SpendEnergy(card.EnergyCost);
							}
						}
					}
					if (!cardWasPlayed)
					{
						Singleton<BoardManager>.Instance.ShowCardNearBoard(card, false);
					}
					__instance.choosingSlotCard = null;
					if ((Object)(object)card != (Object)null && (Object)(object)((Card)card).Anim != (Object)null)
					{
						((Card)card).Anim.SetSelectedToPlay(false);
					}
					__instance.CardsInHand.ForEach(delegate(PlayableCard x)
					{
						((InteractableBase)x).SetEnabled(true);
					});
				}
				else
				{
					yield return enumerator;
				}
			}

			public static IEnumerator ChooseSacrificesForCard(List<CostAndValidSlots> listCostAndValidSlots, PlayableCard card)
			{
				Singleton<ViewManager>.Instance.Controller.LockState = (ViewLockState)0;
				Singleton<ViewManager>.Instance.SwitchToView(Singleton<BoardManager>.Instance.BoardView, false, false);
				Singleton<InteractionCursor>.Instance.ForceCursorType((CursorType)1);
				Singleton<BoardManager>.Instance.cancelledPlacementWithInput = false;
				Singleton<BoardManager>.Instance.currentSacrificeDemandingCard = card;
				Singleton<BoardManager>.Instance.currentValidSlots.Clear();
				foreach (CostAndValidSlots costAndValidSlots in listCostAndValidSlots)
				{
					foreach (CardSlot cardSlot in costAndValidSlots.validSlots)
					{
						Singleton<BoardManager>.Instance.currentValidSlots.Add(cardSlot);
					}
				}
				Singleton<BoardManager>.Instance.CancelledSacrifice = false;
				Singleton<BoardManager>.Instance.LastSacrificesInfo.Clear();
				Singleton<BoardManager>.Instance.SetQueueSlotsEnabled(false);
				foreach (CardSlot allSlot in Singleton<BoardManager>.Instance.AllSlots)
				{
					if (!allSlot.IsPlayerSlot || (Object)(object)allSlot.Card == (Object)null)
					{
						((InteractableBase)allSlot).SetEnabled(false);
						((HighlightedInteractable)allSlot).ShowState((State)1, false, 0.15f);
					}
					if (allSlot.IsPlayerSlot && (Object)(object)allSlot.Card != (Object)null && allSlot.Card.CanBeSacrificed)
					{
						((Card)allSlot.Card).Anim.SetShaking(true);
					}
				}
				yield return Singleton<BoardManager>.Instance.SetSacrificeMarkersShown(((Card)card).Info.BloodCost);
				while (!satisfiesSacrifice(Singleton<BoardManager>.Instance.currentSacrifices, listCostAndValidSlots, card) && !Singleton<BoardManager>.Instance.cancelledPlacementWithInput)
				{
					Singleton<BoardManager>.Instance.SetSacrificeMarkersValue(Singleton<BoardManager>.Instance.currentSacrifices.Count);
					yield return (object)new WaitForEndOfFrame();
				}
				Singleton<BoardManager>.Instance.currentValidSlots.Clear();
				foreach (CardSlot cardSlot2 in Singleton<BoardManager>.Instance.playerSlots)
				{
					Singleton<BoardManager>.Instance.currentValidSlots.Add(cardSlot2);
				}
				foreach (CardSlot allSlot2 in Singleton<BoardManager>.Instance.AllSlots)
				{
					((InteractableBase)allSlot2).SetEnabled(false);
					if (allSlot2.IsPlayerSlot && (Object)(object)allSlot2.Card != (Object)null)
					{
						((Card)allSlot2.Card).Anim.SetShaking(false);
					}
				}
				Plugin.Logger.LogInfo((object)"Selected sacrifices were:");
				foreach (CardSlot currentSacrifice in Singleton<BoardManager>.Instance.currentSacrifices)
				{
					Plugin.Logger.LogInfo((object)("\t- " + ((Card)currentSacrifice.Card).Info.displayedName + " on Slot.Index " + currentSacrifice.Index + "."));
					Singleton<BoardManager>.Instance.LastSacrificesInfo.Add(((Card)currentSacrifice.Card).Info);
				}
				bool flag = !Singleton<BoardManager>.Instance.SacrificesCreateRoomForCard(card, Singleton<BoardManager>.Instance.currentSacrifices);
				if (Singleton<BoardManager>.Instance.cancelledPlacementWithInput || flag)
				{
					Singleton<BoardManager>.Instance.HideSacrificeMarkers();
					if (flag)
					{
						yield return (object)new WaitForSeconds(0.25f);
					}
					foreach (CardSlot slot in Singleton<BoardManager>.Instance.GetSlots(true))
					{
						if ((Object)(object)slot.Card != (Object)null)
						{
							((Card)slot.Card).Anim.SetSacrificeHoverMarkerShown(false);
							if (Singleton<BoardManager>.Instance.currentSacrifices.Contains(slot))
							{
								((Card)slot.Card).Anim.SetMarkedForSacrifice(false);
							}
						}
					}
					Singleton<ViewManager>.Instance.SwitchToView(Singleton<BoardManager>.Instance.defaultView, false, false);
					Singleton<InteractionCursor>.Instance.ClearForcedCursorType();
					Singleton<BoardManager>.Instance.CancelledSacrifice = true;
				}
				else
				{
					Singleton<BoardManager>.Instance.SetSacrificeMarkersValue(Singleton<BoardManager>.Instance.GetValueOfSacrifices(Singleton<BoardManager>.Instance.currentSacrifices));
					yield return (object)new WaitForSeconds(0.2f);
					Singleton<BoardManager>.Instance.HideSacrificeMarkers();
					foreach (CardSlot currentSacrifice2 in Singleton<BoardManager>.Instance.currentSacrifices)
					{
						if ((Object)(object)currentSacrifice2.Card != (Object)null && !currentSacrifice2.Card.Dead)
						{
							BoardManager instance = Singleton<BoardManager>.Instance;
							int sacrificesMadeThisTurn = instance.SacrificesMadeThisTurn;
							instance.SacrificesMadeThisTurn = sacrificesMadeThisTurn + 1;
							yield return currentSacrifice2.Card.Sacrifice();
							Singleton<ViewManager>.Instance.SwitchToView(Singleton<BoardManager>.Instance.BoardView, false, false);
						}
					}
				}
				Singleton<BoardManager>.Instance.SetQueueSlotsEnabled(true);
				foreach (CardSlot allSlot3 in Singleton<BoardManager>.Instance.AllSlots)
				{
					((InteractableBase)allSlot3).SetEnabled(true);
					((HighlightedInteractable)allSlot3).ShowState((State)2, false, 0.15f);
				}
				Singleton<BoardManager>.Instance.currentSacrificeDemandingCard = null;
				Singleton<BoardManager>.Instance.currentSacrifices.Clear();
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public class SacrificesCreateRoomForCard
		{
			[HarmonyPrefix]
			public static bool Prefix(BoardManager __instance, ref bool __result, PlayableCard card, List<CardSlot> sacrifices)
			{
				foreach (CustomCardCost customCardCost in CardExtensions.GetCustomCardCosts((Card)(object)card))
				{
					if (customCardCost is CustomSacrificeCost)
					{
						__result = true;
						return false;
					}
				}
				return true;
			}
		}

		private static readonly Harmony HarmonyInstance = new Harmony("GeckVolantMarin-CustomCardSacrificeCost");

		private static bool satisfiesSacrifice(List<CardSlot> sacrifices, List<CostAndValidSlots> listCostAndValidSlots, PlayableCard card)
		{
			List<CardSlot> sacrifices2 = new List<CardSlot>();
			foreach (CardSlot sacrifice in sacrifices)
			{
				sacrifices2.Add(sacrifice);
			}
			Singleton<BoardManager>.Instance.currentValidSlots.Clear();
			bool result = true;
			foreach (CostAndValidSlots listCostAndValidSlot in listCostAndValidSlots)
			{
				if (!satisfiesOneSacrificeCost(ref sacrifices2, listCostAndValidSlot, card))
				{
					result = false;
				}
			}
			return result;
		}

		private static bool satisfiesOneSacrificeCost(ref List<CardSlot> sacrifices, CostAndValidSlots costAndValidSlots, PlayableCard card)
		{
			int num = 0;
			List<CardSlot> list = new List<CardSlot>();
			foreach (CardSlot sacrifice in sacrifices)
			{
				foreach (CardSlot validSlot in costAndValidSlots.validSlots)
				{
					if (sacrifice.Index != validSlot.Index)
					{
						continue;
					}
					list.Add(sacrifice);
					if ((Object)(object)costAndValidSlots.customSacrificeCost == (Object)null)
					{
						num += Singleton<BoardManager>.Instance.GetValueOfSacrifices(new List<CardSlot> { sacrifice });
						if (num >= CardExtensions.BloodCost(card))
						{
							break;
						}
					}
					else
					{
						num += costAndValidSlots.customSacrificeCost.satisfiesSacrifices(sacrifice.Card);
						if (num >= CardExtensions.GetCustomCostAmount(card, ((CustomCardCost)costAndValidSlots.customSacrificeCost).CostName))
						{
							break;
						}
					}
				}
				if ((Object)(object)costAndValidSlots.customSacrificeCost == (Object)null)
				{
					if (num >= CardExtensions.BloodCost(card))
					{
						break;
					}
				}
				else if (num >= CardExtensions.GetCustomCostAmount(card, ((CustomCardCost)costAndValidSlots.customSacrificeCost).CostName))
				{
					break;
				}
			}
			if ((Object)(object)costAndValidSlots.customSacrificeCost == (Object)null)
			{
				if (num >= CardExtensions.BloodCost(card))
				{
					foreach (CardSlot cardSlot2 in list)
					{
						Singleton<BoardManager>.Instance.currentValidSlots.Add(cardSlot2);
						sacrifices.RemoveAll((CardSlot s) => s.Index == cardSlot2.Index);
					}
					return true;
				}
			}
			else if (num >= CardExtensions.GetCustomCostAmount(card, ((CustomCardCost)costAndValidSlots.customSacrificeCost).CostName))
			{
				foreach (CardSlot cardSlot in list)
				{
					Singleton<BoardManager>.Instance.currentValidSlots.Add(cardSlot);
					sacrifices.RemoveAll((CardSlot s) => s.Index == cardSlot.Index);
				}
				return true;
			}
			foreach (CardSlot validSlot2 in costAndValidSlots.validSlots)
			{
				Singleton<BoardManager>.Instance.currentValidSlots.Add(validSlot2);
			}
			return false;
		}

		public static void register()
		{
			HarmonyInstance.PatchAll(typeof(CustomSacrificeCostPatch).Assembly);
		}
	}
	public class ExempleRabbitSacrificeCost : CustomSacrificeCost
	{
		public static FullCardCost cost;

		public override string CostName => "RabbitSacrificeCost";

		public override int satisfiesSacrifices(PlayableCard card)
		{
			if (((Object)((Card)card).Info).name == "Rabbit")
			{
				return 1;
			}
			return 0;
		}

		public override bool CostSatisfied(int cardCost, PlayableCard card)
		{
			int num = 0;
			foreach (PlayableCard playerCard in BoardManagerExtensions.GetPlayerCards(Singleton<BoardManager>.Instance, (Predicate<PlayableCard>)null))
			{
				if (((Object)((Card)playerCard).Info).name == "Rabbit")
				{
					num++;
				}
			}
			return num >= cardCost;
		}

		public override string CostUnsatisfiedHint(int cardCost, PlayableCard card)
		{
			return "You don't have enough Rabbits on the board to play a " + ((Card)card).Info.DisplayedNameLocalized + ".";
		}

		public override IEnumerator OnPlayed(int cardCost, PlayableCard card)
		{
			yield break;
		}

		public static Texture2D TextureMethod(int cardCost, CardInfo info, PlayableCard card)
		{
			return TextureHelper.GetImageAsTexture($"rabbitSacrificeCost_{cardCost}.png", (FilterMode)0);
		}

		public static Texture2D PixelTextureMethod(int cardCost, CardInfo info, PlayableCard card)
		{
			return Part2CardCostRender.CombineIconAndCount(cardCost, TextureHelper.GetImageAsTexture("rabbitSacrificeCostPixel_7x8.png", (FilterMode)0));
		}

		public static int CostTier(int amount)
		{
			return Mathf.FloorToInt((float)amount * 3f);
		}

		public static bool CanBePlayed(int amount, CardInfo card, List<CardInfo> hand)
		{
			int num = 0;
			foreach (CardInfo item in hand)
			{
				if (((Object)item).name == "Rabbit")
				{
					num++;
				}
			}
			foreach (PlayableCard playerCard in BoardManagerExtensions.GetPlayerCards(Singleton<BoardManager>.Instance, (Predicate<PlayableCard>)null))
			{
				if (((Object)playerCard).name == "Rabbit")
				{
					num++;
				}
			}
			return num >= amount;
		}

		public static void register()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			cost = CardCostManager.Register("GeckVolantMarin-CustomCardSacrificeCost", "RabbitSacrificeCost", typeof(ExempleRabbitSacrificeCost), (Func<int, CardInfo, PlayableCard, Texture2D>)TextureMethod, (Func<int, CardInfo, PlayableCard, Texture2D>)PixelTextureMethod);
			CardCostManager.SetCostTier(cost, (Func<int, int>)CostTier);
			CardCostManager.SetCanBePlayedByTurn2WithHand(cost, (Func<int, CardInfo, List<CardInfo>, bool>)CanBePlayed);
			CardCostManager.SetFoundAtChoiceNodes(cost, true, (Texture)(Texture2D)ResourceBank.Get<Texture>("card_rewardback_rabbitSacrificeCost.png"));
		}
	}
	[BepInPlugin("GeckVolantMarin-CustomCardSacrificeCost", "GeckVolantMarin-CustomCardSacrificeCost", "1.0.0")]
	[BepInProcess("Inscryption.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static string directory;

		private void modifySquirrelForTesting()
		{
			CardExtensions.SetBaseAttackAndHealth(CardExtensions.CardByName((IEnumerable<CardInfo>)CardManager.BaseGameCards, "Squirrel"), (int?)100, (int?)100);
		}

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			directory = ((BaseUnityPlugin)this).Info.Location;
			CustomSacrificeCostPatch.register();
			EnergyDrone.ZoneConfigs[(CardTemple)0].ConfigEnergy = true;
			EnergyDrone.ZoneConfigs[(CardTemple)0].ConfigShowDrone = true;
			EnergyDrone.ZoneConfigs[(CardTemple)0].ConfigDefaultDrone = true;
			EnergyDrone.ZoneConfigs[(CardTemple)0].ConfigMox = true;
			EnergyDrone.ZoneConfigs[(CardTemple)0].ConfigDroneMox = true;
			Logger.LogInfo((object)"Reussi?");
			Logger.LogInfo((object)"Plugin GeckVolantMarin-CustomCardSacrificeCost is loaded!");
		}
	}
}