Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions APIPatcher/APIPatcher.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netframework4.7.2</TargetFramework>
<TargetFrameworks>netframework4.7.2</TargetFrameworks>
<RuntimeIdentifiers>win-x64;win-x86;win-arm64;linux-x64;linux-arm;linux-arm64;linux-musl-x64;linux-musl-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
<AssemblyName>Assembly-CSharp.APIPatcher.mm</AssemblyName>
<Description>The MonoMod Patcher for the Inscryption API.</Description>
<Version>2.24.2</Version>
<Authors>Cyantist, IngoH, WhistleWind, Chaosyr and Contibutors</Authors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>Latest</LangVersion>
<RootNamespace>APIPatcher</RootNamespace>
<DebugType>full</DebugType>
<NoWarn>$(NoWarn);AD0001;CS0612;CS8604;CS0252;CS0618;Harmony003;Publicizer001</NoWarn>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<SelfContained>true</SelfContained>
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
<IncludeBuildOutput>false</IncludeBuildOutput>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<TargetName>Assembly-CSharp.APIPatcher.mm</TargetName>
</PropertyGroup>

<PropertyGroup>
<NoWarn>$(NoWarn);AD0001;CS0612;CS8604;CS0252;CS0618;Harmony003;Publicizer001</NoWarn>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>

<ItemGroup>
Expand All @@ -22,4 +32,16 @@
<ItemGroup>
<ProjectReference Private="false" Include="..\InscryptionAPI\InscryptionAPI.csproj" />
</ItemGroup>

<!--Net Framework References-->
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="all" />
</ItemGroup>

<!--Cleanup Publish for our Build System-->
<Target Name="StripAllNuGetFromPublish" AfterTargets="ComputeFilesToPublish">
<ItemGroup>
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)" Condition="'%(ResolvedFileToPublish.Extension)' == '.dll' and '%(ResolvedFileToPublish.RelativePath)' != 'Assembly-CSharp.APIPatcher.mm.dll'" />
</ItemGroup>
</Target>
</Project>
7 changes: 7 additions & 0 deletions APIPatcher/ScriptableObjectLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@

namespace APIPatcher;

/// <summary>
/// Uses MonoMod to patch Unity's ScriptableObjectLoader to also use our version of the ScriptableObjectLoader seen in the Inscryption API itself.
/// </summary>
/// <typeparam name="T"></typeparam>
[MonoModPatch("global::ScriptableObjectLoader`1")]
internal class patch_ScriptableObjectLoader<T> : ScriptableObjectLoader<T> where T : UnityObject
{
/// <summary>
/// A List of AllData used within the overarching <see cref="ScriptableObjectLoader{T}"/> system, e.g. a List of <see cref="UnityObject"/>.
/// </summary>
new public static List<T> AllData
{
get
Expand Down
13 changes: 13 additions & 0 deletions APIPatcher/Singleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@

namespace APIPatcher;

/// <summary>
/// Uses MonoMod to patch the Singleton for later usability by the Inscryption API.
/// </summary>
/// <typeparam name="T">A ManagedBehaviour associated with the Singleton System.</typeparam>
[MonoModPatch("global::Singleton`1")]
internal class patch_Singleton<T> : Singleton<T> where T : ManagedBehaviour
{
/// <summary>
/// A simple function used to Find a Specified UnityObject of the specified Type within the Active Scene, if it fails it tosses a Warning.
/// </summary>
new protected static void FindInstance()
{
if (m_Instance == null)
Expand All @@ -21,7 +28,13 @@ internal class patch_Singleton<T> : Singleton<T> where T : ManagedBehaviour
}
}

/// <summary>
/// A simple class object for singletons in correlation with the API.
/// </summary>
internal static class Singleton
{
/// <summary>
/// A ManualLogSource specifically for logging issues related to Singletons.
/// </summary>
internal static readonly ManualLogSource SingletonLogSource = Logger.CreateLogSource("Singleton");
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 2.24.2
* Updated Installation Guides to Include Pulsar Mod Manager.
* Added more null checks into the following patches `GainGemsForOpponents`, `LoseGemsForOpponents`, `GainTripleGemsForOpponents`, `LoseTripleGemsForOpponents`.
* Removed `_specialSequencer` from `SpecialSequenceManager` as it was unused.
* Removed `FontReplacementDataInitialized` from `LocalizationManager` as it was unused.
* Added new Support for Custom Appearances.
- Image Handling is to be handled by the mods using the API.
- We now provide a storage of Base Game Decals that mods can reference without needing to instantiate their own.
- This comes with 5 new Dictionaries `BaseGameCustomAppearances` (Internal), `BaseGameCustomAppearancesPublic`, `ModdedCustomAppearancesDictionary` (Internal), `ModdedCustomAppearancesDictionaryPublic`, `CombinedCustomAppearancesDictionaryPublic`.
- This system is stored under the `TextureHelper` class.
* Improved In-Code Documentation via XML Comments.

# 2.24.1
* Added Extensions for setting the IconTexture of a Starter Deck.
* Added 2 Alternate Constructors for making a StarterDeck with a Display Name different from its Internal Name.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions InscryptionAPI/Card/CardExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -412,4 +412,5 @@ public static CardInfo RemoveCardMetaCategories(this CardInfo info, params CardM
public static bool ModPrefixIs(this CardInfo info, string prefixToMatch) => info.GetExtendedProperty("ModPrefix") == prefixToMatch;

#endregion

}
20 changes: 12 additions & 8 deletions InscryptionAPI/Card/OpponentGemsPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,34 @@ private static IEnumerator UpdateGemsOnHookGrab(IEnumerator enumerator)
private static IEnumerator GainGemsForOpponents(IEnumerator enumerator, GainGem __instance)
{
yield return enumerator;
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance != null)
Singleton<OpponentGemsManager>.Instance.AddGem(__instance.Gem);
if (__instance != null && __instance.Card != null)
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance != null)
Singleton<OpponentGemsManager>.Instance.AddGem(__instance.Gem);
}
[HarmonyPostfix, HarmonyPatch(typeof(GainGem), nameof(GainGem.OnDie))]
private static IEnumerator LoseGemsForOpponents(IEnumerator enumerator, GainGem __instance)
{
yield return enumerator;
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance != null)
Singleton<OpponentGemsManager>.Instance.LoseGem(__instance.Gem);
if (__instance != null && __instance.Card != null)
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance != null)
Singleton<OpponentGemsManager>.Instance.LoseGem(__instance.Gem);
}

[HarmonyPostfix, HarmonyPatch(typeof(GainGemTriple), nameof(GainGemTriple.OnResolveOnBoard))]
private static IEnumerator GainTripleGemsForOpponents(IEnumerator enumerator, GainGemTriple __instance)
{
yield return enumerator;
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance)
Singleton<OpponentGemsManager>.Instance.AddGems(GemType.Green, GemType.Orange, GemType.Blue);
if (__instance != null && __instance.Card != null)
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance)
Singleton<OpponentGemsManager>.Instance.AddGems(GemType.Green, GemType.Orange, GemType.Blue);
}
[HarmonyPostfix, HarmonyPatch(typeof(GainGemTriple), nameof(GainGemTriple.OnDie))]
private static IEnumerator LoseTripleGemsForOpponents(IEnumerator enumerator, GainGemTriple __instance)
{
yield return enumerator;
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance != null)
Singleton<OpponentGemsManager>.Instance.LoseGems(GemType.Green, GemType.Orange, GemType.Blue);
if (__instance != null && __instance.Card != null)
if (__instance.Card.OpponentCard && Singleton<OpponentGemsManager>.Instance != null)
Singleton<OpponentGemsManager>.Instance.LoseGems(GemType.Green, GemType.Orange, GemType.Blue);
}

[HarmonyTranspiler, HarmonyPatch(typeof(DiskRenderStatsLayer), nameof(DiskRenderStatsLayer.RenderCard))]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
using DiskCardGame;
using HarmonyLib;
using InscryptionAPI.Guid;
using UnityEngine;

namespace InscryptionAPI.Card.Patches;

/// <summary>
/// A Patch in which injects Loggers and Validation Check Logging into 'GenerateTradeCardsWithCostTier' before it runs to try and debug errors related to it.
/// </summary>
[HarmonyPatch(typeof(TradeCardsForPelts), "GenerateTradeCardsWithCostTier")]
internal static class PatchGenerateTradeCardsWithCostTierWithOptionalDebugLogging
{
/// <summary>
/// Makes our system Log 'GenerateTradeCardsWithCostTier' related issues.
/// </summary>
/// <param name="numCards">The Number Of Cards to Generate.</param>
/// <param name="tier">The Tier of Cards that should be Generated.</param>
/// <param name="randomSeed">The RandomSeed associated with the Generation.</param>
[HarmonyPrefix]
private static void Prefix(int numCards, int tier, int randomSeed)
{
try
{
LogGenerateTradeCardsWithCostTierState(numCards, tier, randomSeed);
}
catch (Exception ex)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] Prefix logging failed. " + $"The original GenerateTradeCardsWithCostTier method will still run. " + $"Exception: {ex}");
}
}
}

/// <summary>
/// A function use to Log relevant info and checks for 'GenerateTradeCardsWithCostTier'.
/// </summary>
/// <param name="numCards">The Number Of Cards to Generate.</param>
/// <param name="requestedTier">The Tier of Cards that should be Generated.</param>
/// <param name="randomSeed">The RandomSeed associated with the Generation.</param>
private static void LogGenerateTradeCardsWithCostTierState(int numCards, int requestedTier, int randomSeed)
{
bool flag = requestedTier > 0;
int effectiveTier = Mathf.Max(1, requestedTier);

if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogDebug($"===== GenerateTradeCardsWithCostTier pre-run ===== " + $"numCards={numCards}, " + $"requestedTier={requestedTier}, " + $"effectiveTier={effectiveTier}, " + $"randomSeed={randomSeed}, " + $"flag={flag}");
}
List<CardInfo> learnedCards = CardLoader.LearnedCards;

if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogDebug($"[TradeCardsForPelts Debug] LearnedCards count before vanilla filtering: {learnedCards.Count}");
}
for (int index = 0; index < learnedCards.Count; index++)
{
CardInfo card = learnedCards[index];

if (card == null)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] NULL CardInfo in CardLoader.LearnedCards " + $"at index={index}.");
}
continue;
}

CardTemple temple;
int costTier;

try
{
temple = card.temple;
costTier = card.CostTier;
}
catch (Exception ex)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] Failed while evaluating vanilla outer predicate | " + $"index={index} | " + $"card={GetCardName(card)} | " + $"exception={ex}");
}
continue;
}

if (temple != CardTemple.Nature || costTier != effectiveTier)
continue;

if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogDebug($"[TradeCardsForPelts Debug] Vanilla ability-filter candidate | " + $"index={index} | " + $"card={GetCardName(card)} | " + $"temple={temple} | " + $"costTier={costTier} | " + $"baseAbilities=[{FormatAbilities(card.abilities)}] | " + $"mods={card.mods?.Count ?? 0}");
}
List<Ability> effectiveAbilities;

try
{
effectiveAbilities = card.Abilities;
}
catch (Exception ex)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] card.Abilities threw while evaluating the " + $"same property vanilla will use | " + $"index={index} | " + $"card={GetCardName(card)} | " + $"exception={ex}");
}
continue;
}

if (effectiveAbilities == null)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] NULL effective CardInfo.Abilities list | " + $"index={index} | " + $"card={GetCardName(card)} | " + $"tier={effectiveTier} | " + $"mods={card.mods?.Count ?? 0}");
}
continue;
}
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogDebug($"[TradeCardsForPelts Debug] Effective abilities | " + $"index={index} | " + $"card={GetCardName(card)} | " + $"abilities=[{FormatAbilities(effectiveAbilities)}]");
}
for (int abilityIndex = 0; abilityIndex < effectiveAbilities.Count; abilityIndex++)
{
Ability ability = effectiveAbilities[abilityIndex];
string abilityName = GetGuidAndKey(ability);

AbilityInfo abilityInfo;

try
{
abilityInfo = AbilitiesUtil.GetInfo(ability);
}
catch (Exception ex)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] AbilitiesUtil.GetInfo threw | " + $"card={GetCardName(card)} | " + $"tier={effectiveTier} | " + $"abilityIndex={abilityIndex} | " + $"ability={abilityName} | " + $"rawValue={(int)ability} | " + $"exception={ex}");
}
continue;
}

if (abilityInfo == null)
{
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogError($"[TradeCardsForPelts Debug] VANILLA NRE CANDIDATE: " + $"AbilitiesUtil.GetInfo returned null | " + $"card={GetCardName(card)} | " + $"tier={effectiveTier} | " + $"abilityIndex={abilityIndex} | " + $"ability={abilityName} | " + $"rawValue={(int)ability} | " + $"baseAbilities=[{FormatAbilities(card.abilities)}] | " + $"effectiveAbilities=[{FormatAbilities(effectiveAbilities)}] | " + $"mods={card.mods?.Count ?? 0} | " + $"vanillaExpression=!AbilitiesUtil.GetInfo(a).opponentUsable");
}
continue;
}

if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogDebug($"[TradeCardsForPelts Debug] Ability lookup OK | " + $"card={GetCardName(card)} | " + $"tier={effectiveTier} | " +
$"abilityIndex={abilityIndex} | " + $"ability={abilityName} | " + $"rawValue={(int)ability} | " + $"opponentUsable={abilityInfo.opponentUsable}");
}
}
}
if (InscryptionAPI.InscryptionAPIPlugin.configEnableTraderCostTierBugDebugLogging.Value)
{
InscryptionAPI.InscryptionAPIPlugin.Logger.LogDebug("===== End GenerateTradeCardsWithCostTier pre-run =====");
}
}

/// <summary>
/// Formats the Passed Abilities as a String.
/// </summary>
/// <param name="abilities">The Abilities to cast into the String.</param>
/// <returns>A Formatted Abilities String.</returns>
private static string FormatAbilities(IEnumerable<Ability> abilities)
{
if (abilities == null)
return "null";

return string.Join(", ", abilities.Select(GetGuidAndKey));
}

/// <summary>
/// Gets a GUID and Key associated with a Ability from the passed in Ability Value.
/// </summary>
/// <param name="ability">The Ability we want to get the String Name of.</param>
/// <returns>A String representing the Ability either via the GUID system or the Enum System.</returns>
private static string GetGuidAndKey(Ability ability)
{
if (GuidManager.TryGetGuidAndKeyEnumValue(ability, out string guid, out string key))
return $"{guid}_{key}";

return ability.ToString();
}

/// <summary>
/// Gets the Card Name and DisplayName of the passed in Card.
/// </summary>
/// <param name="card">The Card to get the Name of.</param>
/// <returns>A string of the Card's Name and DisplayName.</returns>
private static string GetCardName(CardInfo card)
{
if (card == null)
return "null";

string internalName = string.IsNullOrEmpty(card.name) ? "null" : card.name;
string displayedName = string.IsNullOrEmpty(card.DisplayedNameEnglish)
? "null"
: card.DisplayedNameEnglish;

return $"{internalName} ({displayedName})";
}
}
2 changes: 1 addition & 1 deletion InscryptionAPI/Card/Patches/SteelTrapDeathPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using MonoMod.Cil;
using UnityEngine;

namespace InscryptionAPI.Card;
namespace InscryptionAPI.Card.Patches;

/// <summary>
/// Patches the Steal Trap Death system to drop a differed pelt on the case the opposing card has the "SteelTrapPelt" extended property.
Expand Down
2 changes: 1 addition & 1 deletion InscryptionAPI/Costs/CardCostManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ private static void GenerateCustomCostChoices(ref List<CardChoice> __result, int
while (list.Count > 3)
list.RemoveAt(SeededRandom.Range(0, list.Count, randomSeed++));

if (InscryptionAPIPlugin.configRandomChoiceOrder.Value)
if (InscryptionAPIPlugin.configRandomCostChoiceOrder.Value)
list = list.Randomize().ToList();

__result = list;
Expand Down
1 change: 0 additions & 1 deletion InscryptionAPI/Encounters/SpecialSequenceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class FullSpecialSequencer
{
public readonly string Id;

private Type _specialSequencer;
public Type SpecialSequencer { get; private set; }

public FullSpecialSequencer(string id, Type specialSequencer)
Expand Down
Loading
Loading