Coder Social home page Coder Social logo

inscryptionapi's Introduction

API

Inscryption API

This plugin is a BepInEx plugin made for Inscryption as an API. This is the de-facto standard API for Inscryption modders.

It can currently create and modify:

  • Cards
  • Abilities
  • Appearance behaviours
  • Stat Icons
  • Challenges
  • Starter Decks
  • Regions
  • Encounters
  • Totem Tops
  • Consumable Items
  • Gramophone Tracks
  • Talking Cards
  • Custom Costs
  • And much more!

Additionally, a number of quality-of-life patches from the community are included with each release.

Installation (automated)

This is the recommended way to install the API on the game.

Installation (manual)

To install this plugin first you need to install BepInEx as a mod loader for Inscryption. A guide to do this can be found here. Inscryption needs the 86x (32 bit) mono version.
You also need to install MonoMod Loader Inscryption.

  • Copy the 'plugins' folder into 'BepInEx/plugins'.
  • Copy the 'monomod' folder into 'BepInEx/monomod'.
    (If any of these folders do not exist, just create them.)

An example Mod utilising this plugin can be found here.

Modded Save File

With this API installed, an additional 'modded save file' will be created by the game. This file will be found in the 'BepInEx' subdirectory, and contains all save data created by mods that use this API. This file will not automatically be synced to the cloud by Steam.

Community Patches

The following patches from the Inscryption modding community have been included in this package to improve the overall quality-of-life for modding and compatibility.

SigilArtPatch by MADH95Mods

Fixes the art for abilities that previously only appeared in Act 2 so they appear correctly in Act 1 and Act 3

Conduit Attack Fix by MADH95Mods

Fixes the behavior of conduits so they function correctly in Act 1.

Activated Sigil Fix by MADH95Mods

Allows activated sigils to work correctly in Act 1 and Act 3 by clicking the sigil icon on the card.

AnthonysLatchFix by AnthonyPython

Fixes latch sigils to work in Act 1

Sigil Art Fix by Memez4Life

Allows up to 8 sigils to be displayed on cards and adds the option to display merged sigil stamps at the bottom of the card instead of over the artwork (see the config files for more information).

Visually Stackable Sigils by divisionbyz0rro

Combines multiple instances of the same sigil on a single card into a single sigil with a number to free up space on the card.

Cost Render Fix by Void Slime

Displays hybrid cost cards correctly and makes energy and mox show up on act 1 cards

Cost Choice Node fix by Void Slime

If energy/mox cards are in the Act 1 pool, energy and mox card choice nodes will be added to the cost choice node in Act 1.

Sniper Sigil Fix by SpecialAPI

Displays targets for attacks made with the sniper sigil in Act 1.

Act 1 Sentry Fixes by WhistleWind

Fixes a number of bugs caused by the Sentry ability being used in Act 1.

Multi-Act Sigil Compatability Fixes by WhistleWind

Fixes a number of sigils to be usable in all Acts. Sigils include: Mental Gemnastics, Tidal Lock, Hoarder, Vessel Printer, Amorphous, Handy.

Fledgling Sigil Fixes by WhistleWind

Fixes Fledgling in Act 2 to show the correct number of turns until a card evolves, up to 3. Also changes its description to show the correct number of turns.

OverridePixelAbilityIcons by WhistleWind

Fixes the OverrideAbilityIcon method to work in Act 2.

Using the API

Inscryption API 2.0 tries to have you use the original game's objects as much as possible. For example, there are no more 'NewCard' and 'CustomCard' objects; instead, you are responsible to create CardInfo objects yourself and add them. The API does provide a number of helper methods to make this process simpler for you.

For more information, please check out the wiki: https://inscryptionmodding.github.io/InscryptionAPI/wiki/

Contribution

How can you help?

Use the plugin and report bugs you find! Ping us on the Inscryption Modding Discord server in the api channel with what you find.

But really, I want to help develop this mod

Great! We're more than happy to accept help. Either make a pull request to the API's GitHub page or come join us over in the Inscryption Modding Discord.

Can I donate?

Donations are totally not needed, this is a passion project before anything else.

Contributors

Original version by cyantist

Contributors and builders of API 2.0:

  • BobbyShmurner
  • divisionbyz0rro
  • Eri
  • IngoH
  • JamesVeug
  • julian-perge
  • KellyBetty
  • Nevernamed
  • SpecialAPI
  • Void Slime
  • WhistleWind
  • Windows10CE

inscryptionapi's People

Contributors

bobbyshmurner avatar divisionbyz0rro avatar humabhatterzed avatar ingohhacks avatar jamesveug avatar julian-perge avatar kbmackenzie avatar madh95 avatar matz-42 avatar panthr75 avatar pet-slime avatar saxbymod avatar scottwilson0903 avatar specialapi avatar windows10ce avatar xhayper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

inscryptionapi's Issues

[Feature]: Failsafe for if the player has no creatures for the campfires

Detail

If you visit a campfire with no creatures that can be buffed at a campfire, it can softlock you. Reasons you may not have any creatures for the campfire: no creatures in deck, all creatures have a special attack icon, all cards in deck count as pelts or terrain, a mix of the above.

Reason

I think it's reasonable to have something like this in the API, since a mod may have card nodes that give you terrain or pelts, or who knows what, and failsafes are always good to have.

Pseudo Code

There's a part of the campfire code where it looks for all the cards that are valid for the campfire: I would just check if it's more than 0.

NewSpecialAbilities patching throws NRE with null `StatIconInfo` fields

Reason:
When constructing the rulebook pages in the Rulebook patch class, the conditional only checks if the NewSpecialAbility.specialAbilities.Count is greater than zero. If there exists a NewSpecialAbility with a null StatIconInfo object, (int)x.statIconInfo.iconType will throw an NRE since no StatIconInfo object has been set

Steps to replicate:

  1. Create a NewSpecialAbility object, but don't pass in a StatIconInfo object.
var specialAbility = new NewSpecialAbility(typeof(ClassThatHasSpecialCardBehaviour), sId);
ClassThatHasSpecialCardBehaviour.specialTriggeredAbility = specialAbility.specialTriggeredAbility;
  1. Put .dll in plugins to load
  2. NRE is thrown

[Feature]: Handling 'BoxColliders does not support negative scale or size.' excessive logging

Detail

To get rid of this log spam from the vanilla game code:

[Warning: Unity Log] BoxColliders does not support negative scale or size.
The effective box size has been forced positive and is likely to give unexpected collision geometry.
If you absolutely need to use negative scaling you can use the convex MeshCollider. Scene hierarchy path "GameTable/CardBattle/Board_Grimora/OpponentSlots/CardSlot_Grimora (2)/Card (Silbon)/RotatingParent/TombstoneParent/CardAbilityIcons_Part3_Invisible/DefaultIcons_2Abilities/Ability_1"

Class: AbilityIconInteractable
Method: SetFlippedY

The problem lies in this line: float y = (flippedY ? -1f : 1f) * Mathf.Abs(transform.localScale.y);

flippedY being true if if it's the opponent card and the AbilityInfo has flipYIfOpponent set to true.

Reason

This can spam the console window a lot . It's rather ugly to see and I'm personally tired of seeing it.

I've spent some time investigating how to handle this, and ran into a few issues however I'll detail below.

Pseudo Code

This patch will replace the BoxCollider object with a MeshCollider one, like how the warning log says to.

However, the problem with this is that the icon can no longer be right-clicked to view in the rulebook.

 [HarmonyPrefix, HarmonyPatch(nameof(AbilityIconInteractable.SetFlippedY))]
 public static bool ChangeStupidNegativeYScalingLogWarning(AbilityIconInteractable __instance, bool flippedY)
 {
  if (flippedY)
  {
   if (__instance.gameObject.GetComponent<MeshCollider>().IsNull())
   {
    MeshCollider collider = __instance.gameObject.AddComponent<MeshCollider>();
    collider.convex = true;
    collider.sharedMesh = null;
    collider.sharedMesh = __instance.GetComponent<MeshFilter>().mesh;

    UnityObject.Destroy(__instance.GetComponent<BoxCollider>());
    __instance.coll = null;
    __instance.coll = collider;

    return false;
   }
  }

  return true;
 }

I have also tried just Rotating the transform, but has this weird unintended side-effect where it will randomly flip one of your card's sigil icons, and then flip it back without any particular reason:

   float y = 1f * Mathf.Abs(__instance.transform.localScale.y);
   __instance.transform.localScale = new Vector3(__instance.transform.localScale.x, y, __instance.transform.localScale.z);
   __instance.transform.Rotate(new Vector3(0, 0, 180));

Allow both Relative and Aboslute path in TextureHelper

Why?

  • So we don't have to worry about UNC name and Drive name error
  • So we can set our own relative point (aka the DLL itself and not the plugins folder)
  • So new coder won't get confused with the path to their own texture.

Explanation

If we want to get a folder in the dll directory, we have to use the follow code

var RelativeToPlugins = (new Uri(Paths.PluginPath+"/")).MakeRelativeUri(new Uri(Path.GetDirectoryName(base.Info.Location)+"/")).OriginalString.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
// ^ This path is now at the DLL directory ^

Logger.LogInfo(Path.Combine(RelativeToPlugins, "Art", "etc", "etc", "woah.png"));
// {mod-author}-{mod-name}/Art/etc/etc/woah.png

But if we decided to support Absolute path, we will have to use the following code

Logger.LogInfo(Path.Combine(Path.GetDirectoryName(base.Info.Location), "Art", "etc", "etc", "woah.png"));
// C:/Path/to/BepinEx/plugins/{mod-author}-{mod-name}/Art/etc/etc/woah.png

Some solution

  • Add a parameter called "isAbsolute" with the default being false
  • Use System.IO.Path.IsPathRooted to check if it's relative or absolute, and run the logic accordingly
  • Make a seperate function

More

  • Then, why not use System.IO.Path.GetRelativePath then?
  • It doesn't come ship with netstandard2.0

[Feature]: Having easier way to adjust MaxEnergy and EnergyGain per turn without having to patch it Manually, and Having CellColor change

Detail

energymax
As max energy is capped at 6 in vanilla, wish to have an existing harmony patch to adjust the cap, and having the cell itself change color to indicate the adjusted value accordingly.

Reason

This would help to create more freedom of energy card creations, since 6 energy cap isn't really that high of a creation window to work with in terms of card power to cost ratio.

Pseudo Code

if energyCount <= 12 && > 6
{
var cellCount = energyCount - 6

     litUpCell(cellCount, int i)
     {
           While i <= cellCount
           {
            changeColorCellNum(i);
            i++
            }
      }

}

Big FPS drop

Few people on the discord are reporting big fps drops using testing with mods. (Myself included).

Mostly noticeable when in a battle where it can drop down to roughly 30fps.

I tested it on thunderstore with no mods active - even with bepindex off = no lag
Only with bepindex = no lag
Bepindex and api 2.0.2 = big fps drop

Specs:
Graphics: Geforce GTX 1070
CPU: Intel Core i7 8700K (6 cores, 12 threads)
Ram: 16gb DDR4, 1337Mhz
Motherboard: ROG STRIX Z370-E GAMING
Storage: Samsung SSD 970 EVO Plus 1TB

[Bug]: Cloning the opponent's cards before they are queued breaks some functionality (including bounty hunters)

Description

In the latest API update, the following update was made to the Opponent's behavior:

[HarmonyPatch(typeof(Opponent), nameof(Opponent.CreateCard))]
[HarmonyPrefix]
private static bool CloneCardInfo(ref CardInfo cardInfo)
{
    // Dynamic costs require a unique CardInfo to get the playable card
    cardInfo = (CardInfo)cardInfo.Clone();
    return true;
}

Cloning a card does not recreate the mods on the card, and sometimes the cards in the opponent's turn plan will have mods on them. Most notably: bounty hunters. The Bounty Hunter is implemented as a single base card with a unique mod per bounty hunter. When you clone the bounty hunter in the turn plan, you end up with a vanilla Bounty Hunter base without any of the unique identifiers for that bounty hunter. The game then softlocks during the bounty hunter intro sequence because it fails to find any of the required information to properly introduce the bounty hunter.

Reproduction

Play Act 3 (or the P03 KCM mod) until you reach your first bounty hunter. The game will softlock when it tries to introduce it.

Relevant log output

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
DiskCardGame.BountyHunter+<IntroductionSequence>d__4.MoveNext () (at <4bde92741da1454db82522c215e393a6>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <3f8c35799b544274b189c23afcaaf82e>:0)

Code sample

No response

Additional Context

Context for the log output: The BountyHunter.IntroductionSequence method fails with a null reference on the line that attempts to play the bounty hunter dialogue. The variable that is null is "bountyHunterMod," which came from the result of Card.Info.Mods.Find in the second line. The fact that it is null tells us that the Find method failed to find a card mod that had the bounty hunter info on it, and the reason this fails is due to the card being cloned and all mods being stripped.

Softlock at Magnificus Fight Act 2

How to reproduce:
play with the API in act 2.
The magnificus fight softlocks the game.

What I expected to happen:
The game would not softlock if I played with just the API and no other mods.

What actually happened:
the game softlocked.

Latch Problems

Latches are currently broken in act 1 for the following reasons:

  • If a latch is triggered by the card bearing it being sacrificed, the player is softlocked as the game does not allow them to select a card to gain the latch sigil, nor does it allow them to place the card they're sacrificing for, or cancel the sacrifice.
  • Latching a sigil onto a card that has already had a sigil latched onto it will remove the original latched sigil.

Not sure if these issues persist into act 2 with regards to sacrifices, but I dont see why it would suddenly start working.

Improved sigil icons

I've improved some of the act 2 sigils in the act 1 style. You're free to use them in the API
AllGem
SquirrelStrafe
SkeletonStrafe

Automatically disable stuff thats not being used by cards[Feature]:

Detail

Similar to how ATS has a manager to disable sigils that are not being used, Make it so theres a version of that within the api that works for Staticons abillitys Tribes and TribeHeads

Reason

It will stop bloating the game with stuff that doesn't have a use within mods

Pseudo Code

Some sort of section where theres a list of The things listed under detail With a config to disable/enable it

such as

modManager {

"tribes.libary.boneless"
"void.electricution"
"stats.libary.spideratk"
}

Custom Tribes

Ability to add custom tribes to the game and have them function like existing tribes

[Feature]: Remove warning log for finding null instance in API Patcher

Detail

While I can see the usecase to an extent, in Act 2 at least it gets spammed A LOT while in a card battle.

Reason

Unnecessary log spam whenever it's always trying to find a null instance.

image

Pseudo Code

Just get rid of it as a warning log, or add a config option in the .cfg file to enable enhanced logging.

I don't recommend setting it to debug log cuz that will still spam the console window if debugging is enabled.

[Bug] Custom flipped ability textures do not work.

Description

The extension methods on AbilityInfo for SetIcon and SetCustomFlippedTexture do not work correctly - although most people won't see the issues with SetIcon because they set the icon directly using AbilityManager.New/Add

If you use the extension method SetCustomFlippedTexture, the method looks up the FullAbility using AbilityManager.AllAbilities - however, that list contains the latest clone, not the root object. The next time the ability list syncs and clones itself, the changes are lost.

These extension methods need to look up the original objects, not the clones. This will require making the NewAbilities list internal instead of private.

Reproduction

1) Create an ability using AbilityManager.New()
2) Set a custom flipped icon using the extension method SetCustomFlippedTexture()

Relevant log output

N/A

Code sample

No response

Additional Context

No response

Activated abilities no longer work after another ability gets added (Act1/Act3/Finale)

This has been somewhat known for awhile, so I'm creating an official issue to have it tracked.

Steps to reproduce:

  1. Have a card that has an activated ability by default.
  2. During a match, add another ability, any ability, to that same card with the activated ability, usually through temp mods.
  3. Activated ability no longer works through left-clicking.

Screenshot setup. Activated ability pays 2 energy to place a Wyvern card in your hand.
image

This one is a little hard to show, but left-clicking does nothing now, even with 4 energy to use. I should be able to left-click twice.
image

[Bug]: Death/Win card creation when done causes a crash

Description

I expected when i was done it would either go back to act 1 or go to Mag scene

what happened is the game crashsed

Reproduction

Die in act 1
Make deathcard
Enter name
finish dialouge 
Crash / Cam flash

Relevant log output

[Warning: Unity Log] Cannot Prepare a disabled VideoPlayer
[Warning: Singleton] Got null in Singleton<DiskCardGame.PlayerHand>.FindInstance
[Warning: Singleton] Got null in Singleton<DiskCardGame.TurnManager>.FindInstance
[Debug  :InscryptionCommunityPatch] Card pool has energy cards True. Card pool has Gem cards False
[Warning: Singleton] Got null in Singleton<DiskCardGame.PlayerHand>.FindInstance
[Warning: Singleton] Got null in Singleton<DiskCardGame.TurnManager>.FindInstance
[Debug  :InscryptionCommunityPatch] Awaking drone. Exists? ResourceModules(Clone) (DiskCardGame.ResourceDrone)
[Warning: Unity Log] DiskCardGame.CardInfo must be instantiated using the ScriptableObject.CreateInstance method instead of new CardInfo.
[Debug  :InscryptionCommunityPatch] Card pool has energy cards True. Card pool has Gem cards False
[Info   :InscryptionAPI] Pliers (DiskCardGame.ConsumableItemData), RuneHoveringItem (UnityEngine.GameObject), DiskCardGame.PliersItem, HoveringRune


(Seems like this)

Code sample

No response

Additional Context

Full log: https://paste.mod.gg/uhimtqqfiyoh/1

Request: Incompatible and Dependent Challenges

Incompatible - challenges that cannot be selected if you have another challenge active (like triple candle not being selectable if you have single candle active)
Incompatible challenges would turn off the other one when selected.

Dependent - challenges that can only be selected if you have another challenge active (like a harder final boss challenge being reliant on the final boss challenge)
Dependent challenges would turn themselves off when the dependent is turned off.

Ideally there would be some way of showing which challenges are incompatible/dependent, bottom right?

[Feature]: Readme Maker merge

Detail

Merge/Copy+Paste the readme content into the API so it can stay up-to-date and continue to be used.
https://inscryption.thunderstore.io/package/JamesGames/ReadmeMaker/
https://github.com/JamesVeug/InscyptionReadmeMaker/tree/develop

I've made the project as extendable, optimized and readable as possible so it should be easy for lots of people to edit it as needed.

By default the ReadmeMaker is disable from the config so when merging would be a good idea to either keep that for the API or change it to pressing some combination of keys when in-game.

To keep consistency the ReadmeDump.cs could be changed to ReadmeManager.cs

When merging this mods can add their own sections using ReadmeDump.AddSection(new CustomSection())
Adding custom columns is something that others may want to do but I haven't added support for it.

Adding custom costs can be done using ReadmeDump.AddCost(new CustomCost()).
However this does require the user to upload the cost images online somehow since that's how the readme maker exports them!

FINAL NOTES

  1. The images for the Costs will need to be reuploaded somewhere and hand put in incase to keep consistency.
  2. The modified cards section does not work (Couldn't think of how to get this working nicely)

Reason

I'm stopping modding inscryption but the readme maker has been useful for modders and players downloading mods so thought.

Pseudo Code

ReadmeManager.Dump()
Creates a GENERATED_README.md file on the users computer with all the information on cards, encounters, abilities and more.

ReadmeManager.AddSection(new CustomSection())
Adds a new section to the readme maker so when it's dumped it will contain all the information from the users custom section.

ReadmeManager.AddCost(new CustomCost())
Adds a new cost to the cards output by the readme maker so they will show that new cost.

TypeMapper sets fields back to null for CustomCards

When the TypeMapper starts converting the CustomCard object, it will set fields back to null.

Steps to reproduce:

  1. Set default abilities field in CustomCard to new List<Ability>()
  2. Using JSON Loader, add a customAbilities property pointing to a custom made ability (e.g. SigilADay)
{
  "name": "Geck",
  "fieldsToEdit": [
    "customAbilities"
  ],
  "customAbilities": [
    {
      "name": "Evolve Randomly",
      "GUID": "julianperge.inscryption.sigiladay"
    }
  ]
}
  1. Load the game
[Debug  :       API] CustomCard [Geck] abilities is null before adding to custom cards list? [False]

[Message:   BepInEx] Chainloader startup complete
[Info   :       API] Loaded 9 custom abilities into data! Total of [107]
[Debug  :       API] Number of ability IDs to set from NewCard.abilityIds: [0]
[Debug  :       API] Number of ability IDs to set from CustomCard.abilityIds: [1]

[Debug  :       API] CustomCard [Geck] abilities is null before calling AbilityDoesNotExistOrCanStack? [True]

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
APIPlugin.Plugin.AbilityDoesNotExistOrCanStack (System.Collections.Generic.List`1[T] abilities, APIPlugin.AbilityIdentifier id) (at <f5cbbedf94ca49b490549b89e60af4b3>:0)
APIPlugin.Plugin.SetAbilityIdentifiers () (at <f5cbbedf94ca49b490549b89e60af4b3>:0)
APIPlugin.Plugin.Start () (at <f5cbbedf94ca49b490549b89e60af4b3>:0)

Tribe API breaks cost mods / other mods that post-patch get "CardbackTexture"

        [HarmonyPatch(typeof(CardSingleChoicesSequencer), "GetCardbackTexture")]
        [HarmonyPostfix]
        public static void GetCardbackTexture(ref Texture __result, CardChoice choice)
        {
            if (__result == null && choice.resourceType != ResourceType.Blood && choice.resourceType != ResourceType.Bone)
            {
                __result = tribes.Find((x) => x.tribe == choice.tribe).cardback;
            }
        }

the Tribe API searches if the result is null, and not the vanilla blood or bone.

this will (has has) conflict with the community patch [CardCostChoiceNodePatchers.cs] in the API as well as custom costs like the PvZ sun cost, and my life costs. As those will return the initial result of null, but not have any tribe associated with them in the new tribes, leading to a null error.

[Bug:] A challenge goes missing between pages

If you have enough challenges for another page of custom challenges to be used, a challenge goes missing between the pages.

There should be an orange, 0 points challenge between the two pages.
I have also seen this happen with the negative points challenges and the positive points challenges.
image
image

Generic data storage for AbilityIdentifier

Will open up possibilities for jsonloader to support mods that have variable values (like EvolveParams.turnsToEvolve/evolution), meaning users can assign those values themselves

[Bug]: The RespondsToTakeDamage Trigger always returns a Nullref Error

Description

The title here says everything, it seems like the TakeDamage trigger always breaks. If this is not a bug with the api i apologize for submitting this but at this point i dont think anything else could be causing this issue.

Reproduction

1.Create an Ability that uses the TakeDamage Trigger
2.Put that Ability on a Card
3.Let that Card get Damaged in Combat
4.Game Softlocks and error prints in Console

Relevant log output

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
MoreStuffsidk.FlyswarmAbility+<OnTakeDamage>d__3.MoveNext () (at <01eb6d8abace4fbf883aebc9b18b1b16>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <3f8c35799b544274b189c23afcaaf82e>:0)

Code sample

public class FlyswarmAbility : AbilityBehaviour
    {
        public override Ability Ability
        {
            get
            {
                return ability;
            }
        }

        public override bool RespondsToTakeDamage(PlayableCard source)
        {
            return true;
        }

        public override IEnumerator OnTakeDamage(PlayableCard source)
        {
            Plugin.Log.LogWarning("OnTakeDamage Triggered");
 

            yield break;
        }

        public static Ability ability;

    }

Additional Context

No response

[Bug]: Card Sync Removes Mods Applied To Evolutions

Description

CardManager.SyncCardList() removes any card mods applied to evolution cards, tail cards and ice cube cards. This effectively means that rn you can't add custom card mods to card evolutions (or similar card transformations)

Reproduction

Create a custom card
Call `SetEvolve()` and specify a card to evolve into. Make sure to add CardMods
Give the original card the evolve sigil
Slap it in on the board and watch it evolve without any of the mods being applied

Relevant log output

N/A

Code sample

No response

Additional Context

Note that this only happens when `ResyncAll` is called, which mainly happens when you load into the game. So if you call `SetEvolve()` while already in the game, the card will properly evolve.

I've also already created a fix, I just need to create the PR. I'll post a comment when it's ready

Custom Triggers

Suggested this to Division and he told me to leave it here. It'd be really helpful to have custom triggers to allow modders to do more with their cards easier, perhaps as a part of ExtendedAbilityBehaviour.
I've taken the liberty of asking modders what custom triggers would make their lives easier, so here are a few that have guaranteed demand.

OnAddedToHand - Triggers after the card is drawn, and after it has properly been added to the player's hand. Allows you to circumvent the issue that when OnDrawn triggers, the card is not actually considered to be in your hand.
OnBellRung - Triggers when the player hits the turn bell to initiate combat.
OnPreSlotAttackSequence - Triggers before the card does the first attack in it's SlotAttackSequence.
OnPostSlotAttackSequence - Triggers after the card has completed all the attacks it intends to make during that turn sequence. Eg: a card will bifurcated will attack twice, and then run this trigger as it has completed it's attack sequence.
OnPostSingularSlotAttackSlot - Triggers after the card has made an attack, with arguments for what slot was attacked, and if the attack was direct to the opponent. Unlike OnPostAttackSequence, this would trigger once for each attack made (eg: twice for bifurcated).
OnScalesChanged - Triggers when the opponent or player take direct damage, after the scales animation plays.
OnUpkeepInHand - Triggers at the start of each turn, when the card is still in the hand. Basic upkeep trigger does not activate in the hand.
OnOtherCardResolveInHand - Triggers when another card resolves on the board while the bearer is still in the hand. Basic other card resolve trigger does not activate in the hand.
OnTurnEndInHand - Triggers at the end of each turn when the card is still in the hand. Same deal as the other in hand triggers.
OnOtherCardDrawnInHand - Triggers when you draw another card while the bearer is in the hand. Again, the basic other card drawn trigger doesnt work in the hand.
OnOtherCardAssignedToSlotInHand - Triggers when another card is assigned to the slot while this card is in the hand. Same deal as the other in hand triggers.
OnOtherCardPreDeathInHand - Same parameters as the base OtherCardPreDeath but works only while the card is in the hand.

Request: region intro dialogue

Been messing with the region manager and trying out custom regions. Noticed there is no section to easily add intro region dialogue. would be helpful for modders in the future if that is just included in the region manager.

[Bug]: List of currently known bugs and issues (Updated: November 28, 2023)

For the purpose of keeping everyone up-to-date and just being all neat and orderly about this, I've decided to post my to-do list a list of currently known issues and bugs, that don't already have their own post here.

This list will be updated as new reports come in and fixes are released.

Known bugs and issues

Key
+ : Fix completed, waiting for release
= : Fix in-progress
? : More info needed

-? Ijiraq card softlocking the game when transforming
-? Game softlocks when the player has a totem for a custom tribe/ability from a mod that's been removed

If you encounter any issues whilst using mods, please seek help on the modding Discord. Issues relating to the API should be reported in the #api channel or here.

GetOpposingSlots makes an additional call if an ability inherits an ability that extends ExtendedAbilityBehaviour

Setup:

  1. Create an ability that extends ExtendedAbilityBehaviour. For this example, let's say AbilityExt.
  2. Create an ability that extends from AbilityExt. Let's call this ChildAbility.
  3. Override RespondsToGetOpposingSlots to true in AbilityExt.
  4. Override GetOpposingSlots to return a set of slots in AbilityExt. Any number of slots will do.
  5. ChildAbility does not override anything, and just creates the ability and added to any card.
  6. When GetOpposingSlots is called for ChildAbility, ChildAbility GetOpposingSlots is called and then AbilityExt GetOpposingSlots is called.

Short log:

[Info   :GrimoraMod] [GiantStrike] Opposing slots is now [0, 1]
[Info   :GrimoraMod] [GiantStrikeEnraged] Opposing slots is now [0, 1]

See these 2 abilities for a more in-depth technical explanation.
Ability that extends ExtendedAbilityBehaviour: https://github.com/julian-perge/GrimoraMod/blob/test/merges/Abilities/Normal/GiantStrike.cs

Child ability that extends GiantStrike: https://github.com/julian-perge/GrimoraMod/blob/test/merges/Abilities/Normal/GiantStrikeEnraged.cs

[Feature]: Add support for act 2 Temples

Detail

Basicaly alter deck will have arrows leading to more pages of Scrybe temples

Reason

For custom scrybes it would be great to have a tab for your scrybes cards

Pseudo Code

Temple new exampleTemple;

exampleTemple = {
"Texture": "exampleTexture.png"
"Name": "Example In Game Name"
}

[FEATURE]: Deload unused tribes and costs at nodes if unused

Detail

If a card doesn't use a tribe or cost deload or disable them at card draws

And have a way to make it do so even with amalgam/gecks

Reason

Some mods don't use all the tribes or costs in their mod

Pseudo Code

A new bool for tribes and costs called ShouldDeload and by default its set to true

[Feature]: Handle Tail On Hit + Sentry interaction exception

Detail

Setup:

  1. Player Card with Sentry in lane 1.
  2. Opponent card in lane 1 has Tail On Hit.
  3. Player Card attacks, triggering Tail On Hit for opponent card.
  4. Opponent Card moves to lane 2, tail spawns in lane 1.
  5. Sentry gets triggered from player card, attacks tail in lane 1.
  6. Tail dies.
  7. Player Card cannot finish attack sequence as the opposing card no longer exists.

Reason

There's already a patch for fixing Default Evolve params, I figured this wouldn't be too much of a hassle to patch since mods are able to have abilities across all acts, causing interactions like this to happen.

Similar to the DefaultEvolve params fix, a HarmonyILManipulator should be sufficient to add the null check in the conditional mentioned in the Pseudo Code portion.

Pseudo Code

In CombatPhaseManager.SlotAttackSlot, right after the trigger for Trigger.CardGettingAttacked happens.

A null check is needed for checking the opposing slot card, like so:

Before:
if (attackingCard != null && attackingCard.Slot != null)

Expected conditional after:
if (attackingCard != null && attackingCard.Slot != null && opposingSlot.Card != null)

Trigger Finder Error

If you delete a card in the hand during the end of a turn (for example if you have a sigil that makes a card in the hand delete itself on turn end) it causes an error in the trigger finder.
image

Below is the code I used to cause this error:
image
image

It's the same way Dead Hand's sigil discards cards, so fixing this error will likely avoid any errors that might be ran into with Dead Hand. (for example if a card in the hand has the OtherCardResolveInHand and gets discarded by Dead Hand's effect)

New abilities do not properly stack

Right now, if you create a new ability and mark it as stackable ('canStack' = true), the ability will not properly stack. Only one trigger is ever added to the card.

Remove prefix-insensitive card searching from GetCardByName

The API patches CardLoader.GetCardByName to use prefix-insensitive card searching:

else if (retVal is null && cardName.EndsWith("_" + name))
{
    retVal = card;
}

This means that if I look for a card named, say, "Example", it has the possibility to return a card named "SomeMod_Example".

However, this has three flaws:

  1. This has the potential to break any card with underscores in the name (for example, "!GIANTCARD_MOON")
  2. If this feature was to be used properly, it would defeat the purpose of using prefixes; if I searched for a card named "Rat" I could either get "ModA_Rat" or "ModB_Rat", even though prefixes are used to stop things like that from happening.
  3. Altering the functionality of a method modders commonly use is just generally a bad idea and can cause difficult-to-fix bugs.

[Feature]: Deathcards can gain costs other than Blood and Bones

Detail

Currently, deathcards can only gain blood and bone costs. Instead, they should be able to gain any cost: blood, bone, energy, mox, and modded costs.

The vanilla costs would be the easy part, but the modded costs would likely lead to needing to add extended properties to CardModificationInfo, since that's all that deathcards really are.

Reason

This is really something that should be in all mods, as it's a vanilla part of the game that doesn't accommodate mods, and having it in the API make it way easier to do, as the full list of extended properties on a card is actually privated.

Pseudo Code

The first step would likely be to add extended properties to CardModificationInfos, then you could do something like this:
image

Where you just add all of the properties. I don't think there's actually anything in the API that differentiates extended properties that are being used for costs, but I could be wrong.

Unable to purchase items with P03 in KM

I have been recently running P03 in KM and noticed that there are no items in my inventory. This is especially the case regardless of what kinds of challenge parameters I set. Also, whenever I have enough robobucks to buy an item the screen doesn't change and there is no selection of items at all. I am including some .txt files showing the red font error messages I receive. Is there anything in the config files that can fix this problem?
Error Message for Items unavailable.txt
Secondary Error Message on Items.txt

[Feature]: Cost Modifications as TemporaryMods

Cost modifications already exist in CardInfo, but are not used in PlayableCard: this means that you cannot use TemporaryMods to change a card's cost.
I would love to use TemporaryMods to change a card's cost, since I have a lot of ideas that I haven't been able to make.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.