using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Configuration;
using TrainworksReloaded.Core;
using TrainworksReloaded.Core.Extensions;
using UnityEngine;
[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("mt2_freecompany.Plugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.4.0")]
[assembly: AssemblyInformationalVersion("0.2.4+dff5fb012995bde1d1cc97759d03cc3272576dc9")]
[assembly: AssemblyProduct("mt2_freecompany.Plugin")]
[assembly: AssemblyTitle("mt2_freecompany.Plugin")]
[assembly: AssemblyVersion("0.2.4.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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]
[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]
[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 mt2_freecompany.Plugin
{
public sealed class CardEffectAllRooms : CardEffectBase
{
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
string paramStr = cardEffectState.GetParamStr();
if (string.IsNullOrEmpty(paramStr))
{
Log("CardEffectAllRooms: falta param_str con el nombre del efecto interno.");
yield break;
}
Type type = typeof(CardEffectBase).Assembly.GetType(paramStr);
if (type == null)
{
Log("CardEffectAllRooms: no existe la clase '" + paramStr + "' en Assembly-CSharp.");
yield break;
}
object? obj = Activator.CreateInstance(type);
CardEffectBase val = (CardEffectBase)((obj is CardEffectBase) ? obj : null);
if (val == null)
{
Log("CardEffectAllRooms: '" + paramStr + "' no es un CardEffectBase.");
yield break;
}
val.Setup(cardEffectState);
List<CharacterState> list = new List<CharacterState>();
coreGameManagers.GetMonsterManager().AddCharactersToList(list);
List<CharacterState> list2 = new List<CharacterState>();
foreach (CharacterState item in list)
{
if ((Object)(object)item != (Object)null && !item.IsDead)
{
list2.Add(item);
}
}
if (list2.Count == 0)
{
Log("CardEffectAllRooms: no hay unidades vivas a las que aplicarlo.");
yield break;
}
List<CharacterState> lista = cardEffectParams.targets;
if (lista == null)
{
Log("CardEffectAllRooms: cardEffectParams.targets es null.");
yield break;
}
List<CharacterState> previos = new List<CharacterState>(lista);
lista.Clear();
lista.AddRange(list2);
Log($"CardEffectAllRooms: {paramStr} sobre {list2.Count} unidades de todos los pisos.");
IEnumerator ejecutar = val.ApplyEffect(cardEffectState, cardEffectParams, coreGameManagers, sysManagers);
while (ejecutar.MoveNext())
{
yield return ejecutar.Current;
}
lista.Clear();
lista.AddRange(previos);
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectConsumeFromHand : CardEffectBase
{
public override bool CanApplyInPreviewMode => false;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
CardPool pool = cardEffectState.GetParamCardPool();
if ((Object)(object)pool == (Object)null)
{
Log("ConsumeFromHand: falta param_card_pool.");
yield break;
}
CardManager cardManager = coreGameManagers.GetCardManager();
if ((Object)(object)cardManager == (Object)null)
{
Log("ConsumeFromHand: no hay CardManager.");
yield break;
}
bool incluirJugada = cardEffectState.GetParamBool();
CardState jugada = cardEffectParams.playedCard;
List<CardState> hand = cardManager.GetHand(true);
int consumidas = 0;
foreach (CardState item in hand)
{
if (item == null || (item == jugada && !incluirJugada))
{
continue;
}
string cardDataID = item.GetCardDataID();
if (!string.IsNullOrEmpty(cardDataID) && pool.Contains(cardDataID) && cardManager.IsCardInHand(item))
{
DiscardCardParams val = new DiscardCardParams
{
discardCard = item,
wasPlayed = false
};
IEnumerator consumir = cardManager.ConsumeCardWithoutPlaying(val);
while (consumir.MoveNext())
{
yield return consumir.Current;
}
consumidas++;
}
}
Log($"ConsumeFromHand: consumidas {consumidas} cartas de la mano (jugada incluida: {incluirJugada}).");
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectGrantOnce : CardEffectBase
{
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
CardPool paramCardPool = cardEffectState.GetParamCardPool();
if ((Object)(object)paramCardPool == (Object)null)
{
Log("GrantOnce: falta param_card_pool.");
yield break;
}
SaveManager saveManager = coreGameManagers.GetSaveManager();
if ((Object)(object)saveManager == (Object)null)
{
Log("GrantOnce: no hay SaveManager.");
yield break;
}
SubtypeData paramSubtype = cardEffectState.GetParamSubtype();
bool flag = paramSubtype != null && !paramSubtype.IsNone;
foreach (CardState item in saveManager.GetDeckState())
{
if (item == null)
{
continue;
}
if (flag)
{
CharacterData spawnCharacterData = item.GetSpawnCharacterData();
if ((Object)(object)spawnCharacterData == (Object)null)
{
continue;
}
foreach (SubtypeData subtype in spawnCharacterData.GetSubtypes())
{
if (subtype != null && subtype.Key == paramSubtype.Key)
{
Log("GrantOnce: ya hay en el mazo una carta con el subtipo '" + paramSubtype.Key + "', no se da nada.");
yield break;
}
}
}
else
{
string cardDataID = item.GetCardDataID();
if (!string.IsNullOrEmpty(cardDataID) && paramCardPool.Contains(cardDataID))
{
Log("GrantOnce: '" + cardDataID + "' ya esta en el mazo, no se da otra.");
yield break;
}
}
}
string paramStr = cardEffectState.GetParamStr();
if (string.IsNullOrEmpty(paramStr))
{
Log("GrantOnce: falta param_str con el nombre del efecto interno.");
yield break;
}
Type type = typeof(CardEffectBase).Assembly.GetType(paramStr);
if (type == null)
{
Log("GrantOnce: no existe la clase '" + paramStr + "' en Assembly-CSharp.");
yield break;
}
object? obj = Activator.CreateInstance(type);
CardEffectBase val = (CardEffectBase)((obj is CardEffectBase) ? obj : null);
if (val == null)
{
Log("GrantOnce: '" + paramStr + "' no es un CardEffectBase.");
yield break;
}
val.Setup(cardEffectState);
Log("GrantOnce: la carta no estaba en el mazo; ejecutando " + paramStr + ".");
IEnumerator ejecutar = val.ApplyEffect(cardEffectState, cardEffectParams, coreGameManagers, sysManagers);
while (ejecutar.MoveNext())
{
yield return ejecutar.Current;
}
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectIfAllyHasUpgrade : CardEffectBase
{
private const string PluginGuid = "mt2_freecompany.Plugin";
private static string NombreMejora(string upgradeId)
{
return "mt2_freecompany.Plugin-Upgrade-" + upgradeId;
}
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
string paramStr = cardEffectState.GetParamStr();
if (string.IsNullOrEmpty(paramStr))
{
Log("IfAllyHasUpgrade: falta param_str con el id de la mejora a buscar.");
yield break;
}
CardUpgradeData val = BuscarMejora(coreGameManagers.GetAllGameData(), paramStr);
if ((Object)(object)val == (Object)null)
{
Log("IfAllyHasUpgrade: NO ENCUENTRO la mejora " + NombreMejora(paramStr) + ".");
yield break;
}
List<CharacterState> list = new List<CharacterState>();
coreGameManagers.GetMonsterManager().AddCharactersToList(list);
bool flag = false;
foreach (CharacterState item in list)
{
if (!((Object)(object)item == (Object)null) && !item.IsDead)
{
if (item.HasUpgrade(val))
{
Log("IfAllyHasUpgrade: '" + item.GetName() + "' lleva '" + paramStr + "' en la unidad.");
flag = true;
break;
}
CardState spawnerCard = item.GetSpawnerCard();
if (spawnerCard != null && spawnerCard.HasUpgrade(val))
{
Log("IfAllyHasUpgrade: '" + item.GetName() + "' lleva '" + paramStr + "' en la carta que la invoco.");
flag = true;
break;
}
}
}
if (!flag)
{
Log("IfAllyHasUpgrade: ningun aliado vivo lleva '" + paramStr + "' (ni en la unidad ni en su carta); no se aplica nada. Aliados vivos: " + ContarVivos(list) + ".");
}
else
{
CardEffectAddCardUpgradeToUnits val2 = new CardEffectAddCardUpgradeToUnits();
((CardEffectBase)val2).Setup(cardEffectState);
Log("IfAllyHasUpgrade: hay un aliado con '" + paramStr + "'; aplicando la mejora.");
IEnumerator ejecutar = ((CardEffectBase)val2).ApplyEffect(cardEffectState, cardEffectParams, coreGameManagers, sysManagers);
while (ejecutar.MoveNext())
{
yield return ejecutar.Current;
}
}
}
private static string ContarVivos(List<CharacterState> aliados)
{
int num = 0;
List<string> list = new List<string>();
foreach (CharacterState aliado in aliados)
{
if (!((Object)(object)aliado == (Object)null) && !aliado.IsDead)
{
num++;
if (list.Count < 6)
{
list.Add(aliado.GetName() + ((aliado.GetSpawnerCard() == null) ? " (sin carta)" : ""));
}
}
}
return num + " -> " + string.Join(", ", list);
}
private static CardUpgradeData? BuscarMejora(AllGameData gameData, string upgradeId)
{
string text = NombreMejora(upgradeId);
foreach (CardUpgradeData allCardUpgradeDatum in gameData.GetAllCardUpgradeData())
{
if ((Object)(object)allCardUpgradeDatum != (Object)null && ((Object)allCardUpgradeDatum).name == text)
{
return allCardUpgradeDatum;
}
}
return null;
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectIfSubtypeInDrawPile : CardEffectBase
{
private static readonly FieldInfo? ClavesDeSubtipo = typeof(CharacterData).GetField("subtypeKeys", BindingFlags.Instance | BindingFlags.NonPublic);
private static bool? ultimoResultado;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
SubtypeData paramSubtype = cardEffectState.GetParamSubtype();
if (paramSubtype == null || paramSubtype.IsNone)
{
return Recordar(resultado: false, "falta param_subtype");
}
CardManager cardManager = coreGameManagers.GetCardManager();
if ((Object)(object)cardManager == (Object)null)
{
return Recordar(resultado: false, "no hay CardManager");
}
string key = paramSubtype.Key;
int num = Contar(cardManager.GetHand(false), key);
if (num > 0)
{
return Recordar(resultado: true, $"{num} en la mano");
}
int num2 = Contar(cardManager.GetDrawPile(false), key);
if (num2 > 0)
{
return Recordar(resultado: true, $"{num2} en la pila de robo");
}
int num3 = Contar(cardManager.GetDiscardPile(false), key);
if (num3 > 0)
{
return Recordar(resultado: true, $"{num3} en el descarte");
}
return Recordar(resultado: false, "no hay ninguna en mano, robo ni descarte");
}
private static int Contar(List<CardState> pila, string buscado)
{
if (pila == null)
{
return 0;
}
int num = 0;
foreach (CardState item in pila)
{
if (item == null)
{
continue;
}
CharacterData spawnCharacterData = item.GetSpawnCharacterData();
if ((Object)(object)spawnCharacterData == (Object)null)
{
continue;
}
if (ClavesDeSubtipo?.GetValue(spawnCharacterData) is List<string> list)
{
foreach (string item2 in list)
{
if (item2 == buscado)
{
num++;
break;
}
}
continue;
}
foreach (SubtypeData subtype in spawnCharacterData.GetSubtypes())
{
if (subtype != null && subtype.Key == buscado)
{
num++;
break;
}
}
}
return num;
}
private static bool Recordar(bool resultado, string motivo)
{
if (ultimoResultado != resultado)
{
ultimoResultado = resultado;
Log("IfSubtypeInPiles: " + (resultado ? "SI" : "NO") + " se puede lanzar (" + motivo + ").");
}
return resultado;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
Log("IfSubtypeInPiles: guarda superada, sigue la cadena de efectos.");
yield break;
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectOfferRandomFromPool : CardEffectBase
{
public override bool CanApplyInPreviewMode => false;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
CardPool paramCardPool = cardEffectState.GetParamCardPool();
if ((Object)(object)paramCardPool == (Object)null)
{
Log("OfferRandomFromPool: falta param_card_pool.");
yield break;
}
CardManager cardManager = coreGameManagers.GetCardManager();
if ((Object)(object)cardManager == (Object)null)
{
Log("OfferRandomFromPool: no hay CardManager.");
yield break;
}
SubtypeData paramSubtype = cardEffectState.GetParamSubtype();
if (paramSubtype != null && !paramSubtype.IsNone)
{
SaveManager saveManager = coreGameManagers.GetSaveManager();
if ((Object)(object)saveManager == (Object)null)
{
Log("OfferRandomFromPool: no hay SaveManager.");
yield break;
}
foreach (CardState item in saveManager.GetDeckState())
{
if (item == null)
{
continue;
}
CharacterData spawnCharacterData = item.GetSpawnCharacterData();
if ((Object)(object)spawnCharacterData == (Object)null)
{
continue;
}
foreach (SubtypeData subtype in spawnCharacterData.GetSubtypes())
{
if (subtype != null && subtype.Key == paramSubtype.Key)
{
Log("OfferRandomFromPool: ya hay en el mazo una carta con el subtipo '" + paramSubtype.Key + "', no se ofrece nada.");
yield break;
}
}
}
}
int numCards = paramCardPool.GetNumCards();
if (numCards <= 0)
{
Log("OfferRandomFromPool: el pool esta vacio.");
yield break;
}
int num = cardEffectState.GetParamInt();
if (num <= 0)
{
num = 1;
}
if (num > numCards)
{
num = numCards;
}
int num2 = cardManager.GetMaxHandSize() - cardManager.GetNumCardsInHand();
if (num2 <= 0)
{
Log("OfferRandomFromPool: la mano esta llena, no se ofrece nada.");
yield break;
}
if (num > num2)
{
Log($"OfferRandomFromPool: solo caben {num2} cartas en la mano; se recorta la oferta.");
num = num2;
}
List<int> list = new List<int>(numCards);
for (int i = 0; i < numCards; i++)
{
list.Add(i);
}
for (int num3 = numCards - 1; num3 > 0; num3--)
{
int index = RandomManager.Range(0, num3 + 1, (RngId)6);
int value = list[num3];
list[num3] = list[index];
list[index] = value;
}
List<string> list2 = new List<string>();
for (int j = 0; j < num; j++)
{
CardData cardAtIndex = paramCardPool.GetCardAtIndex(list[j]);
if (!((Object)(object)cardAtIndex == (Object)null))
{
cardManager.AddNewCard(cardAtIndex, (CardPile)3, false, false, (AddCardUpgradingInfo)null, true);
list2.Add(((GameData)cardAtIndex).GetID());
}
}
Log(string.Format("OfferRandomFromPool: ofrecidas {0} de {1} cartas del pool a la mano: {2}.", list2.Count, numCards, string.Join(", ", list2)));
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectRefreshAbilityOnKill : CardEffectBase
{
private sealed class Estado
{
public bool activacionEnCurso;
public bool mato;
}
private static readonly ConditionalWeakTable<CharacterState, Estado> estados = new ConditionalWeakTable<CharacterState, Estado>();
private static readonly PropertyInfo? PropEstado = typeof(CharacterState).GetProperty("PrimaryStateInformation", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
public override bool CanApplyInPreviewMode => false;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
int paramInt = cardEffectState.GetParamInt();
List<CharacterState> targets = cardEffectParams.targets;
if (targets == null || targets.Count == 0)
{
Log($"RefreshAbilityOnKill[{paramInt}]: sin objetivo (target_mode tiene que ser self).");
yield break;
}
foreach (CharacterState item in targets)
{
if ((Object)(object)item == (Object)null || !item.HasUnitAbility())
{
continue;
}
Estado orCreateValue = estados.GetOrCreateValue(item);
switch (paramInt)
{
case 0:
orCreateValue.activacionEnCurso = true;
orCreateValue.mato = false;
break;
case 1:
if (orCreateValue.activacionEnCurso || HabilidadResolviendose(item))
{
orCreateValue.mato = true;
Log("RefreshAbilityOnKill: muerte durante la habilidad; la recarga se quita al terminar.");
}
else
{
int num2 = QuitarRecarga(item);
Log($"RefreshAbilityOnKill: muerte fuera de la habilidad; quitadas {num2} de recarga.");
}
break;
case 2:
if (orCreateValue.mato)
{
int num = QuitarRecarga(item);
Log($"RefreshAbilityOnKill: la habilidad mato; quitadas {num} de recarga, lista otra vez.");
}
orCreateValue.activacionEnCurso = false;
orCreateValue.mato = false;
break;
default:
Log($"RefreshAbilityOnKill: param_int {paramInt} no es 0, 1 ni 2.");
break;
}
}
}
private static int QuitarRecarga(CharacterState unidad)
{
int statusEffectStacks = unidad.GetStatusEffectStacks("cooldown");
if (statusEffectStacks > 0)
{
unidad.RemoveStatusEffect("cooldown", statusEffectStacks, true);
}
return statusEffectStacks;
}
private static bool HabilidadResolviendose(CharacterState unidad)
{
try
{
object obj = PropEstado?.GetValue(unidad);
FieldInfo fieldInfo = obj?.GetType().GetField("isUnitAbilityResolving", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
bool flag = default(bool);
int num;
if (fieldInfo != null)
{
object value = fieldInfo.GetValue(obj);
if (value is bool)
{
flag = (bool)value;
num = 1;
}
else
{
num = 0;
}
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
catch
{
return false;
}
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectRequisition : CardEffectBase
{
private const string PluginGuid = "mt2_freecompany.Plugin";
private static readonly Dictionary<string, string[]> Escaleras = new Dictionary<string, string[]>
{
["Sub_Warrior"] = new string[3] { "Buckler", "KiteShield", "BulwarkPlate" },
["Sub_Barbarian"] = new string[3] { "NotchedAxe", "TwinAxes", "ReaversMaul" },
["Sub_Rogue"] = new string[3] { "Lockpicks", "PoisonedDagger", "ThiefsMantle" },
["Sub_Wizard"] = new string[3] { "ChalkCircle", "Grimoire", "ArchmagesStaff" },
["Sub_Cleric"] = new string[3] { "Bandages", "HolySymbol", "Reliquary" },
["Sub_Ranger"] = new string[3] { "Shortbow", "Longbow", "GreatBow" }
};
private static readonly Random Azar = new Random();
public override bool CanPlayWhenHandFull => false;
private static string ClaveSubtipo(string rolId)
{
return "SubtytpesData_nameKey-mt2_freecompany.Plugin-Subtype-" + rolId;
}
private static string NombreCarta(string cardId)
{
return "mt2_freecompany.Plugin-Card-" + cardId;
}
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
SaveManager saveManager = coreGameManagers.GetSaveManager();
if ((Object)(object)saveManager != (Object)null && saveManager.PreviewMode)
{
return false;
}
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
int num = cardEffectState.GetParamInt();
if (num < 1 || num > 3)
{
Log($"Requisition: param_int={num} fuera de 1..3; se usa 1.");
num = 1;
}
SaveManager saveManager = coreGameManagers.GetSaveManager();
if ((Object)(object)saveManager != (Object)null && saveManager.PreviewMode)
{
yield break;
}
AllGameData allGameData = coreGameManagers.GetAllGameData();
CardManager cardManager = coreGameManagers.GetCardManager();
if ((Object)(object)allGameData == (Object)null || (Object)(object)cardManager == (Object)null)
{
Log("Requisition: falta AllGameData o CardManager.");
yield break;
}
CharacterState val = null;
List<CharacterState> targets = cardEffectParams.targets;
if (targets != null && targets.Count > 0)
{
val = targets[0];
}
if ((Object)(object)val == (Object)null)
{
Log("Requisition: no hay objetivo; revisa target_mode en el JSON.");
yield break;
}
string text = null;
foreach (KeyValuePair<string, string[]> escalera in Escaleras)
{
if (TieneSubtipo(val, escalera.Key))
{
text = escalera.Value[num - 1];
break;
}
}
if (text == null)
{
List<string[]> list = new List<string[]>(Escaleras.Values);
text = list[Azar.Next(list.Count)][num - 1];
Log("Requisition: objetivo sin subtipo de rol (vistos: " + ListarSubtipos(val) + "); al azar sale " + text + ".");
}
CardData val2 = BuscarCarta(allGameData, text);
if ((Object)(object)val2 == (Object)null)
{
Log("Requisition: NO ENCUENTRO la carta " + NombreCarta(text) + ".");
}
else if (cardManager.AddNewCard(val2, (CardPile)3, false, false, (AddCardUpgradingInfo)null, true) == null)
{
Log("Requisition: AddNewCard devolvio null para " + text + " (mano llena?).");
}
else
{
Log($"Requisition: a la mano {text} (escalon {num}).");
}
}
private static CardData? BuscarCarta(AllGameData gameData, string cardId)
{
string text = NombreCarta(cardId);
foreach (CardData allCardDatum in gameData.GetAllCardData())
{
if ((Object)(object)allCardDatum != (Object)null && ((Object)allCardDatum).name == text)
{
return allCardDatum;
}
}
return null;
}
private static bool TieneSubtipo(CharacterState target, string rolId)
{
string text = ClaveSubtipo(rolId);
foreach (SubtypeData subtype in target.GetSubtypes())
{
if (subtype != null && subtype.Key == text)
{
return true;
}
}
return false;
}
private static string ListarSubtipos(CharacterState target)
{
List<string> list = new List<string>();
foreach (SubtypeData subtype in target.GetSubtypes())
{
if (subtype != null)
{
list.Add(subtype.Key);
}
}
if (list.Count != 0)
{
return string.Join(", ", list);
}
return "(ninguno)";
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectRingPyreDamage : CardEffectBase
{
private const int PorAnilloPorDefecto = 5;
private const int TopePorDefecto = 11;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override string GetDescriptionAsTrait(CardEffectState cardEffectState)
{
AllGameManagers instance = AllGameManagers.Instance;
SaveManager val = ((instance != null) ? instance.GetSaveManager() : null);
if ((Object)(object)val == (Object)null)
{
return string.Empty;
}
int num = CalcularDano(cardEffectState, val.GetDisplayDistance());
return $"Pyre damage this Ring: <b>{num}</b>";
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
SaveManager saveManager = coreGameManagers.GetSaveManager();
if ((Object)(object)saveManager == (Object)null)
{
Log("RingPyreDamage: no hay SaveManager.");
}
else
{
if (saveManager.PreviewMode)
{
yield break;
}
PlayerManager playerManager = coreGameManagers.GetPlayerManager();
if ((Object)(object)playerManager == (Object)null)
{
Log("RingPyreDamage: no hay PlayerManager.");
yield break;
}
int displayDistance = saveManager.GetDisplayDistance();
int num = CalcularDano(cardEffectState, displayDistance);
if (num <= 0)
{
Log($"RingPyreDamage: anillo {displayDistance}, dano {num} -> no se aplica nada.");
yield break;
}
playerManager.AdjustTowerHP(-num, true);
int num2 = cardEffectState.GetParamInt();
if (num2 <= 0)
{
num2 = 5;
}
int num3 = cardEffectState.GetAdditionalParamInt();
if (num3 <= 0)
{
num3 = 11;
}
Log($"RingPyreDamage: anillo {displayDistance}, {num2} x ({num3} - {displayDistance}) = {num} de dano a la pira.");
}
}
private static int CalcularDano(CardEffectState cardEffectState, int anillo)
{
int num = cardEffectState.GetParamInt();
if (num <= 0)
{
num = 5;
}
int num2 = cardEffectState.GetAdditionalParamInt();
if (num2 <= 0)
{
num2 = 11;
}
return Math.Max(0, num * (num2 - anillo));
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public sealed class CardEffectWidowsPension : CardEffectBase
{
public override bool CanApplyInPreviewMode => false;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
int multiplo = cardEffectState.GetParamInt();
if (multiplo <= 0)
{
multiplo = 5;
}
PlayerManager jugador = coreGameManagers.GetPlayerManager();
List<CharacterState> targets = cardEffectParams.targets;
if ((Object)(object)jugador == (Object)null || targets == null)
{
yield break;
}
foreach (CharacterState item in targets)
{
if ((Object)(object)item == (Object)null)
{
continue;
}
string detalle;
int num = Calcular(item, multiplo, out detalle);
Log($"WidowsPension: {item} -> {num} de oro ({detalle}).");
if (num > 0)
{
IEnumerator pago = jugador.AdjustGold(num, true);
while (pago.MoveNext())
{
yield return pago.Current;
}
}
}
}
private static int Calcular(CharacterState unidad, int multiplo, out string detalle)
{
CardState spawnerCard = unidad.GetSpawnerCard();
CharacterData val = ((spawnerCard != null) ? spawnerCard.GetSpawnCharacterData() : null) ?? unidad.GetSourceCharacterData();
if ((Object)(object)val == (Object)null)
{
detalle = "sin carta ni datos de personaje";
return 0;
}
int num = val.GetAttackDamage();
int num2 = val.GetHealth();
CardStateModifiers val2 = ((spawnerCard != null) ? spawnerCard.GetCardStateModifiers() : null);
if (val2 != null)
{
num = CardStateModifiers.GetUpgradedStatValue(num, (StatType)0, (CardStateModifiers[])(object)new CardStateModifiers[1] { val2 });
num2 = CardStateModifiers.GetUpgradedStatValue(num2, (StatType)1, (CardStateModifiers[])(object)new CardStateModifiers[1] { val2 });
}
int num3 = Math.Max(0, num) + Math.Max(0, num2);
int result = (int)Math.Round((double)num3 / (double)multiplo, MidpointRounding.AwayFromZero) * multiplo;
detalle = $"ataque {num} + vida {num2} = {num3}, redondeo a {multiplo}";
return result;
}
private static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
internal static class Countdowns
{
internal sealed class Pendiente
{
public int dano;
public CardState? carta;
}
internal sealed class PorUnidad
{
public readonly Dictionary<string, Pendiente> pendientes = new Dictionary<string, Pendiente>();
public readonly Dictionary<string, int> ultimoPiso = new Dictionary<string, int>();
}
internal static readonly ConditionalWeakTable<CharacterState, PorUnidad> tabla = new ConditionalWeakTable<CharacterState, PorUnidad>();
internal static void Log(string mensaje)
{
Plugin.Logger.LogInfo((object)mensaje);
}
}
public class CardEffectPlantCountdown : CardEffectDamage
{
private static bool avisoPrevia;
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
int paramInt = cardEffectState.GetParamInt();
StatusEffectStackData[] paramStatusEffectStackData = cardEffectState.GetParamStatusEffectStackData();
if (paramStatusEffectStackData == null || paramStatusEffectStackData.Length == 0)
{
Countdowns.Log("PlantCountdown: falta param_status_effects.");
yield break;
}
List<CharacterState> targets = cardEffectParams.targets;
if (targets == null)
{
yield break;
}
foreach (CharacterState item in targets)
{
if ((Object)(object)item == (Object)null || item.IsDestroyed || !item.IsAlive)
{
continue;
}
StatusEffectStackData[] array;
if (item.PreviewMode)
{
if (!avisoPrevia)
{
avisoPrevia = true;
Countdowns.Log("PlantCountdown: [previa sin acumular] la vista previa pone el estado pero no apunta dano.");
}
array = paramStatusEffectStackData;
foreach (StatusEffectStackData val in array)
{
if (val != null && !string.IsNullOrEmpty(val.statusId))
{
item.AddStatusEffect(val.statusId, val.count, (CharacterState)null, true, false);
}
}
continue;
}
Countdowns.PorUnidad orCreateValue = Countdowns.tabla.GetOrCreateValue(item);
array = paramStatusEffectStackData;
foreach (StatusEffectStackData val2 in array)
{
if (val2 != null && !string.IsNullOrEmpty(val2.statusId))
{
item.AddStatusEffect(val2.statusId, val2.count, (CharacterState)null, true, false);
if (!orCreateValue.pendientes.TryGetValue(val2.statusId, out Countdowns.Pendiente value))
{
value = new Countdowns.Pendiente();
orCreateValue.pendientes[val2.statusId] = value;
}
value.dano += paramInt;
value.carta = cardEffectParams.playedCard;
orCreateValue.ultimoPiso[val2.statusId] = PisoDe(item);
Countdowns.Log($"PlantCountdown: {val2.statusId} x{val2.count} en {item}, dano pendiente {value.dano}.");
}
}
}
}
internal static int PisoDe(CharacterState unidad)
{
RoomState currentRoom = unidad.GetCurrentRoom(false);
if (!((Object)(object)currentRoom != (Object)null))
{
return -1;
}
return currentRoom.GetRoomIndex();
}
}
public sealed class CardEffectCountdownTick : CardEffectBase
{
public override bool CanApplyInPreviewMode => false;
public override PropDescriptions CreateEditorInspectorDescriptions()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new PropDescriptions();
}
public override bool TestEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers)
{
return true;
}
public override IEnumerator ApplyEffect(CardEffectState cardEffectState, CardEffectParams cardEffectParams, ICoreGameManagers coreGameManagers, ISystemManagers sysManagers)
{
StatusEffectStackData[] estados = cardEffectState.GetParamStatusEffectStackData();
List<CharacterState> targets = cardEffectParams.targets;
if (estados == null || targets == null)
{
yield break;
}
foreach (CharacterState unidad in targets)
{
if ((Object)(object)unidad == (Object)null || unidad.IsDestroyed || !unidad.IsAlive)
{
continue;
}
Countdowns.PorUnidad info = Countdowns.tabla.GetOrCreateValue(unidad);
int piso = CardEffectPlantCountdown.PisoDe(unidad);
StatusEffectStackData[] array = estados;
foreach (StatusEffectStackData val in array)
{
if (val == null || string.IsNullOrEmpty(val.statusId))
{
continue;
}
int statusEffectStacks = unidad.GetStatusEffectStacks(val.statusId);
if (statusEffectStacks <= 0 || (info.ultimoPiso.TryGetValue(val.statusId, out var value) && value == piso))
{
continue;
}
info.ultimoPiso[val.statusId] = piso;
unidad.RemoveStatusEffect(val.statusId, 1, true);
Countdowns.Log($"CountdownTick: {val.statusId} {statusEffectStacks} -> {statusEffectStacks - 1} en {unidad} (piso {piso}).");
if (statusEffectStacks - 1 > 0)
{
continue;
}
CardState playedCard = null;
int num;
if (info.pendientes.TryGetValue(val.statusId, out Countdowns.Pendiente value2))
{
num = value2.dano;
playedCard = value2.carta;
info.pendientes.Remove(val.statusId);
}
else
{
num = ValorDelEstado(coreGameManagers, val.statusId);
Countdowns.Log($"CountdownTick: sin dano apuntado para {val.statusId}; uso el param_int del estado, {num}.");
}
if (num > 0)
{
Countdowns.Log($"CountdownTick: {val.statusId} a 0, {num} de dano a {unidad}.");
ApplyDamageToTargetParameters val2 = new ApplyDamageToTargetParameters
{
playedCard = playedCard,
damageType = (Type)0
};
IEnumerator golpe = coreGameManagers.GetCombatManager().ApplyDamageToTarget(num, unidad, val2);
while (golpe.MoveNext())
{
yield return golpe.Current;
}
if ((Object)(object)unidad == (Object)null || unidad.IsDestroyed || !unidad.IsAlive)
{
break;
}
}
}
}
}
private static int ValorDelEstado(ICoreGameManagers coreGameManagers, string statusId)
{
StatusEffectManager statusEffectManager = coreGameManagers.GetStatusEffectManager();
StatusEffectData val = ((statusEffectManager != null) ? statusEffectManager.GetStatusEffectDataById(statusId, true) : null);
if (val == null)
{
return 0;
}
return val.GetParamInt();
}
}
public sealed class StatusEffectFreeCompanyCountdownState : StatusEffectState
{
public override bool TestTrigger(InputTriggerParams inputTriggerParams, OutputTriggerParams outputTriggerParams, ICoreGameManagers coreGameManagers)
{
return false;
}
public override int GetEffectMagnitude(int stacks = 1)
{
CharacterState associatedCharacter = ((StatusEffectState)this).GetAssociatedCharacter();
if ((Object)(object)associatedCharacter != (Object)null && Countdowns.tabla.TryGetValue(associatedCharacter, out Countdowns.PorUnidad value) && value.pendientes.TryGetValue(((StatusEffectState)this).GetStatusId(), out Countdowns.Pendiente value2))
{
return value2.dano;
}
return ((StatusEffectState)this).GetParamInt();
}
}
[BepInPlugin("mt2_freecompany.Plugin", "mt2_freecompany.Plugin", "0.2.4")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger = new ManualLogSource("mt2_freecompany.Plugin");
public void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Railhead.GetBuilder().Configure("mt2_freecompany.Plugin", (Action<IConfigurationBuilder>)delegate(IConfigurationBuilder c)
{
ConfigurationExtensions.AddMergedJsonFile(c, new List<string>(77)
{
"json/plugin.json", "json/champions/champion_roderic.json", "json/champions/champion_roderic_wall.json", "json/champions/champion_roderic_quartermaster.json", "json/champions/champion_roderic_plunder.json", "json/champions/champion_vesper.json", "json/champions/champion_vesper_grimoire.json", "json/champions/champion_vesper_chirurgeon.json", "json/champions/champion_vesper_beastmaster.json", "json/cards/card_magic_missile.json",
"json/cards/card_shield_wall.json", "json/units/unit_battle_chaplain.json", "json/units/unit_berserker.json", "json/units/unit_bounty_hunter.json", "json/units/unit_camp_brawler.json", "json/units/unit_chapel_acolyte.json", "json/units/unit_cutpurse.json", "json/units/unit_fieldmedic.json", "json/units/unit_free_lance.json", "json/units/unit_hedge_conjurer.json",
"json/units/unit_hedgemage.json", "json/units/unit_ironbound_champion.json", "json/units/unit_longbowman.json", "json/units/unit_master_of_coin.json", "json/units/unit_sellsword_scout.json", "json/units/unit_shieldbearer.json", "json/units/unit_the_new_guy.json", "json/units/unit_troll.json", "json/spells/spell_banishment.json", "json/spells/spell_bless.json",
"json/spells/spell_cloudkill.json", "json/spells/spell_cure_wounds.json", "json/spells/spell_delayed_blast_fireball.json", "json/spells/spell_dimension_door.json", "json/spells/spell_fear.json", "json/spells/spell_finger_of_death.json", "json/spells/spell_fireball.json", "json/spells/spell_grease.json", "json/spells/spell_haste.json", "json/spells/spell_invisibility.json",
"json/spells/spell_lightning_bolt.json", "json/spells/spell_mass_hold_person.json", "json/spells/spell_mercenarys_contract.json", "json/spells/spell_paid_in_full.json", "json/spells/spell_resurrection.json", "json/spells/spell_shield.json", "json/spells/spell_silence.json", "json/spells/spell_spoils_of_war.json", "json/spells/spell_web.json", "json/spells/spell_severance_pay.json",
"json/spells/spell_kit_bash.json", "json/spells/spell_double_shift.json", "json/rooms/room_caltrops.json", "json/rooms/room_paymasters_tent.json", "json/rooms/room_rope_and_grapple.json", "json/rooms/room_the_pit.json", "json/rooms/room_quartermasters_store.json", "json/rooms/room_watchtower.json", "json/kits/kit_barbarian.json", "json/kits/kit_cleric.json",
"json/kits/kit_ranger.json", "json/kits/kit_rogue.json", "json/kits/kit_warrior.json", "json/kits/kit_wizard.json", "json/equipment/equip_widows_pension.json", "json/relics/relic_butchers_bill.json", "json/relics/relic_expanded_billet.json", "json/relics/relic_field_forge.json", "json/relics/relic_hazard_pay.json", "json/relics/relic_letter_of_marque.json",
"json/relics/relic_marching_orders.json", "json/relics/relic_quartermasters_seal.json", "json/relics/relic_sappers_charges.json", "json/relics/relic_scouts_map.json", "json/relics/relic_veterans_papers.json", "json/relics/relic_war_chest.json", "json/status/status_countdown.json"
});
});
Logger.LogInfo((object)"Plugin mt2_freecompany.Plugin is loaded!");
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "mt2_freecompany.Plugin";
public const string PLUGIN_NAME = "mt2_freecompany.Plugin";
public const string PLUGIN_VERSION = "0.2.4";
}
}