foul-magics/Mage/src/main/java/mage/abilities/LoyaltyAbility.java
Alex Vasile a2162ec3e7
Refactor: private fields and performance tweaks (#9625)
1a. Make `costs`, `manaCosts`, and `manaCostsToPay` private in `AbilityImpl` with access through getters/setters 
1b. fix cost adjuster for imprinted cards affected by the above

2a. Lazy instantiation for rarely used `data` field in `TargetPointerImpl`

3a. Pre-allocate certain array sizes in `Modes` and `CostsImpl`

4a. Make `manaTemplate` private in `BasicManaEffect`, copy when passing outside the class 
4b. Don't copy `manaTemplate` in copy constructor since it doesn't change 
4c. Add comments explaining copy usage for `manaTemplate` 
4d. Remove redundant variable assignment and make fields final 

---------

Co-authored-by: xenohedron <xenohedron@users.noreply.github.com>
2023-08-27 17:58:19 -04:00

90 lines
3.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mage.abilities;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayLoyaltyCost;
import mage.abilities.costs.common.PayVariableLoyaltyCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.constants.TimingRule;
import mage.constants.Zone;
/**
* @author BetaSteward_at_googlemail.com
*/
public class LoyaltyAbility extends ActivatedAbilityImpl {
public LoyaltyAbility(Effect effect, int loyalty) {
super(Zone.BATTLEFIELD, effect, new PayLoyaltyCost(loyalty));
this.timing = TimingRule.SORCERY;
}
public LoyaltyAbility(Effects effects, int loyalty) {
super(Zone.BATTLEFIELD, effects, new PayLoyaltyCost(loyalty));
this.timing = TimingRule.SORCERY;
}
public LoyaltyAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, new PayVariableLoyaltyCost());
this.timing = TimingRule.SORCERY;
}
public LoyaltyAbility(Effects effects) {
super(Zone.BATTLEFIELD, effects, new PayVariableLoyaltyCost());
this.timing = TimingRule.SORCERY;
}
public LoyaltyAbility(LoyaltyAbility ability) {
super(ability);
}
@Override
public LoyaltyAbility copy() {
return new LoyaltyAbility(this);
}
/**
* Change loyalty cost by amount value
*
* @param amount
*/
public void increaseLoyaltyCost(int amount) {
// loyalty cost modification rules from Carth the Lion
// If a planeswalkers loyalty ability normally has a cost of [+1], Carths ability makes it cost [+2] instead.
// A cost of [0] would become [+1], and a cost of [-6] would become [-5].
// (2021-06-18)
//
// If you somehow manage to control two Carths (perhaps because of Spark Double), the cost-changing effect is
// cumulative. In total, loyalty abilities will cost an additional [+2] to activate.
// (2021-06-18)
//
// The total cost of a planeswalkers loyalty ability is calculated before any counters are added or removed.
// If a loyalty ability normally costs [-3] to activate, you do not remove three counters from it and then
// put one counter on it. You remove two counters at one time when you pay the cost.
// (2021-06-18)
//
// If an effect replaces the number of counters that would be placed on a planeswalker, such as that of
// Vorinclex, Monstrous Raider, that replacement happens only once, at the time payment is made.
// (2021-06-18)
// cost modification support only 1 cost item
int staticCount = 0;
for (Cost cost : getCosts()) {
if (cost instanceof PayLoyaltyCost) {
// static cost
PayLoyaltyCost staticCost = (PayLoyaltyCost) cost;
staticCost.setAmount(staticCost.getAmount() + amount);
staticCount++;
} else if (cost instanceof PayVariableLoyaltyCost) {
// x cost (after x announce: x cost + static cost)
PayVariableLoyaltyCost xCost = (PayVariableLoyaltyCost) cost;
xCost.setCostModification(xCost.getCostModification() + amount);
}
}
if (staticCount > 1) {
throw new IllegalArgumentException(String.format("Loyalty ability must have only 1 static cost, but has %d: %s",
staticCount, this.getRule()));
}
}
}