-
Notifications
You must be signed in to change notification settings - Fork 22
Powers (Buffs)
Power
is the game's general term for all buffs and debuffs that go on the player or enemies, not to be confused with Power cards, which are cards that usually apply Power
s to the player.
All powers extend from the AbstractPower
class. The BasePower
class extends from AbstractPower
and provides some additional utility to make it easier to set up.
An example of a power that increases the damage of attacks (basically Strength):
public class NotStrengthPower extends BasePower {
public static final String POWER_ID = makeID("NotStrength");
private static final AbstractPower.PowerType TYPE = AbstractPower.PowerType.BUFF;
private static final boolean TURN_BASED = false;
//The only thing TURN_BASED controls is the color of the number on the power icon.
//Turn based powers are white, non-turn based powers are red or green depending on if their amount is positive or negative.
//For a power to actually decrease/go away on its own they do it themselves.
//Look at powers that do this like VulnerablePower and DoubleTapPower.
public NotStrengthPower(AbstractCreature owner, int amount) {
super(POWER_ID, TYPE, TURN_BASED, owner, amount);
}
public float atDamageGive(float damage, DamageInfo.DamageType type) {
//If NORMAL (attack) damage, modify damage by this power's amount
return type == DamageInfo.DamageType.NORMAL ? damage + this.amount : damage;
}
public void updateDescription() {
this.description = DESCRIPTIONS[0] + amount + DESCRIPTIONS[1];
}
}
The text for powers is loaded from PowerStrings.json
, and accessed using the DESCRIPTIONS
array. In this example, you would put something like this
"${modID}:NotStrength": {
"NAME": "Not Strength",
"DESCRIPTIONS": [
"Attacks deal #b",
" additional damage."
]
}
into the PowerStrings.json
file under localization.
"DESCRIPTIONS": [
"Attacks deal #b", <- This is DESCRIPTIONS[0]
" additional damage." <- DESCRIPTIONS[1]
]
This results in the description made by
this.description = DESCRIPTIONS[0] + amount + DESCRIPTIONS[1];
being
Attacks deal #b? additional damage.
Numbers in power descriptions are always blue, which is what the #b
is for, which colors the text it's attached to. Keywords should be capitalized and colored yellow using #y
.
The base game generally does all its descriptions in parts like this, and putting them together in the description based on certain conditions.
BasePower
loads its images from the modid/images/powers
folder in resources. For this example power with the ID being makeID("NotStrength")
, you would need an ~30x30 image at modid/images/powers/NotStrength.png
, and an optional ~84x84 higher resolution version at modid/images/powers/large/NotStrength.png
. The large version is used for an image flash vfx that occurs when a power is applied. If it is not provided, it will just scale up the lower resolution version, which can look quite pixelated. The sizes of these images don't have to be exact. A 32x32 image with an empty margin is around the size you want for the icon. The filled space should be around 28x28.
If you want to check the power (using AbstractDungeon.player.getPower/hasPower), use the POWER_ID
field. Typing the ID yourself is prone to errors and also wouldn't be changed if you adjusted the power's ID later.
ex. if (AbstractDungeon.player.hasPower(NotStrengthPower.POWER_ID)) {
Regardless of whether a power is a buff or debuff, or intended to be applied to the player or an enemy, powers are always applied using an ApplyPowerAction
.
The constructor of ApplyPowerAction
you'll be using most often is
public ApplyPowerAction(AbstractCreature target, AbstractCreature source, AbstractPower powerToApply)
Target and source are relatively self-explanatory; if a player uses a card to buff themselves, the target and source would both be the player. If the player uses a card to debuff an enemy, the target would be the enemy and the source would be the player.
Next is the power to be applied. This will just be a new instance of whatever power you want to apply. The only thing to remember is that the power's owner must match the target of the action.
For a card that says "Gain !M! NotStrength." the code would be
@Override
public void use(AbstractPlayer p, AbstractMonster m) {
addToBot(new ApplyPowerAction(p, p, new NotStrengthPower(p, magicNumber)));
}
ApplyPowerAction
also has constructors with more parameters. You won't need these often, but you should still know what they're for.
The next parameter is stackAmount
. When applying a power to a target, if the target doesn't already have that power, then the instance you give to the action is directly applied to the target. If the target already has that power, instead, the already existing power's amount will be adjusted by stackAmount
.When stackAmount
is not provided, ApplyPowerAction
will just use the amount of the power you're applying, which is why it isn't necessary most of the time. A case where you might want it to be different is for certain powers that can't be stacked, such as Barricade. In cases like this, you can use 0, or even just check if the player has the power before adding the ApplyPowerAction
to the queue. Non-stacking powers generally use -1 for their amount, as negative numbers are normally not displayed unless canGoNegative
is set to true in the power's constructor.
After stackAmount
, the next parameter is either boolean isFast
or AttackEffect effect
.
isFast
simply makes the ApplyPowerAction
faster, with less delay before the next action will happen. This is used if you're applying many powers at the same time, such as debuffing all enemies.
effect
causes the ApplyPowerAction
to use an AttackEffect
which are generally used by the DamageAction
class as a visual/sound effect.