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!");
}
}
}