-
Notifications
You must be signed in to change notification settings - Fork 5
Creating New Modifiers
To make a new modifier, first make a class which extends AbstractAugment. Augments are an extension of Card Modifiers, and offer additional hooks to use.
Your modifier must provide an override for getModRarity, validCard, and makeCopy.
Your modifier should always override identifier, for testing if your modifier happens to be on a card.
Your modifier should override getPrefix and getSuffix, even if it only uses one, translations might change the wording around! Modifying the card name like this allows people to know at a glance what modifier they rolled.
Common, Uncommon, and Rare modifiers will spawn in pools. Special modifiers will not.
The following is a Common modifier which does nothing and cannot spawn on any cards.
public class MyAugment extends AbstractAugment {
public static final String ID = MyMod.makeID(MyAugment.class.getSimpleName());
@Override
public AugmentRarity getModRarity() {
return AugmentRarity.COMMON;
}
@Override
public boolean validCard(AbstractCard card) {
return false;
}
@Override
public AbstractCardModifier makeCopy() {
return new MyAugment();
}
@Override
public String identifier(AbstractCard card) {
return ID;
}
}As Augments extend CardModifiers, you have access to all cardmod hooks to use, and more! The extra hooks you get access to are as follows:
//Uses the same logic as a startup card. The return value is if the card should show on screen.
public boolean atBattleStartPreDraw(AbstractCard card)
//On card upgrade
public void onUpgradeCheck(AbstractCard card)
//Triggers whenever you take damage, like Masterful Stab
public void onDamaged(AbstractCard card)
//Lets you prevent other cards from being played while a card with this mod is in your hand, like Normality
public boolean betterCanPlay(AbstractCard cardWithThisMod, AbstractCard cardToCheck)Augments have many helper functions you can use if you want to filter what can it can spawn on. It also supports searching of all possible upgrades a card can have (Branching and MultiUpgrades included). To search through these upgrade stats, you can use a cardCheck call.
public static boolean cardCheck(AbstractCard card, Predicate<AbstractCard> p)Some premade helper functions are as follows:
//Checks if the character is an orb user or has prismatic shard
public static boolean allowOrbMods()
//Checks if the player has any curse in the master deck
public static boolean hasACurse()
//Check any given player state, such as being a certain character, having a certain relic, being under certain HP, etc.
public static boolean characterCheck(Predicate<AbstractPlayer> p)
//Is not a Curse or Status
public static boolean isNormalCard(AbstractCard card)
//Doesnt Exhaust, Purge, or use Exhaustive
public static boolean doesntExhaust(AbstractCard cardThere are also helper functions designed to use with cardCheck, as they check the state of all possible upgrades as well
//True if the card upgrades the variable
public static boolean upgradesDamage()
public static boolean upgradesBlock()
public static boolean upgradesMagic()
//True if the card or any upgrade has at least the specified amount
public static boolean reachesDamage(int amount)
public static boolean reachesBlock(int amount)
public static boolean reachesMagic(int amount)
//True if the state doesnt change when upgraded
public static boolean doesntUpgradeCost()
public static boolean doesntUpgradeExhaust()
public static boolean doesntUpgradeEthereal()
public static boolean doesntUpgradeInnate()
public static boolean doesntUpgradeRetain()
public static boolean doesntUpgradeReshuffle()
public static boolean doesntUpgradeTargeting()
//True if the card never has the effect, even if upgraded
public static boolean notExhaust(AbstractCard card)
public static boolean notEthereal(AbstractCard card)
public static boolean notInnate(AbstractCard card)
public static boolean notRetain(AbstractCard card)
public static boolean notReshuffle(AbstractCard card)
//True if the card always targets an enemy
public static boolean usesEnemyTargeting()
//True if you can change the card target to the specified type without causing issues
public static boolean canOverrideTargeting(AbstractCard card, AbstractCard.CardTarget desiredType)
//True if the card uses magicNumber
public static boolean usesMagic(AbstractCard card)
//True if the card uses magicNumber and also doesnt lower on upgrade it like Berserk
public static boolean doesntDowngradeMagic()Finally, there are some helper functions to let you perform basic introspection on what the card does
//True if the card doesnt implement any interfaces
public static boolean noInterfaces(AbstractCard card)
//True if the card doesnt override the specified method
public static boolean doesntOverride(AbstractCard card, String method, Class<?>... paramtypez)
//True if the card adds the specified action to the queue
public static boolean usesAction(AbstractCard card, Class<? extends AbstractGameAction> clazz)
//True if the card creates a new object of the specified class
public static boolean usesClass(AbstractCard card, final Class<?> clazz)For example, a card which only spawns on Attacks that upgrade their damage and do not Exhaust would use:
@Override
public boolean validCard(AbstractCard card) {
return card.type == AbstractCard.CardType.ATTACK && cardCheck(card, c -> upgradesDamage() && notExhaust(c));
}Here is an example of a Common modifier that increases the amount of damage it deals when upgraded by 3, but only if the card already upgrades damage, doesnt have Exhaust, and hasnt been upgraded yet.
public class MyAugment extends AbstractAugment {
//The ID should be prefixed with your modID.
public static final String ID = MyMod.makeID(MyAugment.class.getSimpleName());
//You can store the text in whatever format, this example uses UIStrings
public static final String[] TEXT = CardCrawlGame.languagePack.getUIString(ID).TEXT;
@Override
public String getPrefix() {
return TEXT[0];
}
@Override
public String getSuffix() {
return TEXT[1];
}
@Override
public AugmentRarity getModRarity() {
return AugmentRarity.COMMON;
}
@Override
public boolean validCard(AbstractCard card) {
return !card.upgraded && card.type == AbstractCard.CardType.ATTACK && cardCheck(card, c -> upgradesDamage() && notExhaust(c));
}
@Override
public void onUpgradeCheck(AbstractCard card) {
card.baseDamage += 3;
card.upgradedDamage = true;
}
@Override
public AbstractCardModifier makeCopy() {
return new MyAugment();
}
@Override
public String identifier(AbstractCard card) {
return ID;
}
}