mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 13:32:06 -08:00
[MH2] Implemented Carth the Lion (#7848)
* [MH2] Implemented Carth the Lion * [MH2] Carth the Lion - Fixed loyalty cost modification * Fix copy constructor and add getters/setters * Call sourceObject.adjustCosts before checking cost modifications * Add unit test * Added additional comments, checks and tests; Co-authored-by: Oleg Agafonov <jaydi85@gmail.com>
This commit is contained in:
parent
3ea08e1e7b
commit
29d3f96340
7 changed files with 353 additions and 24 deletions
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
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;
|
||||
|
|
@ -9,7 +9,6 @@ import mage.constants.TimingRule;
|
|||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class LoyaltyAbility extends ActivatedAbilityImpl {
|
||||
|
|
@ -43,4 +42,49 @@ public class LoyaltyAbility extends ActivatedAbilityImpl {
|
|||
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 planeswalker’s loyalty ability normally has a cost of [+1], Carth’s 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 planeswalker’s 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 : costs) {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.LoyaltyAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.counters.CounterType;
|
||||
|
|
@ -11,19 +11,14 @@ import mage.game.permanent.Permanent;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PayLoyaltyCost extends CostImpl {
|
||||
|
||||
private final int amount;
|
||||
private int amount;
|
||||
|
||||
public PayLoyaltyCost(int amount) {
|
||||
this.amount = amount;
|
||||
this.text = Integer.toString(amount);
|
||||
if (amount > 0) {
|
||||
this.text = '+' + this.text;
|
||||
}
|
||||
setAmount(amount);
|
||||
}
|
||||
|
||||
public PayLoyaltyCost(PayLoyaltyCost cost) {
|
||||
|
|
@ -34,7 +29,26 @@ public class PayLoyaltyCost extends CostImpl {
|
|||
@Override
|
||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||
Permanent planeswalker = game.getPermanent(source.getSourceId());
|
||||
return planeswalker != null && planeswalker.getCounters(game).getCount(CounterType.LOYALTY) + amount >= 0 && planeswalker.canLoyaltyBeUsed(game);
|
||||
if (planeswalker == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int loyaltyCost = amount;
|
||||
|
||||
// apply cost modification
|
||||
if (ability instanceof LoyaltyAbility) {
|
||||
LoyaltyAbility copiedAbility = ((LoyaltyAbility) ability).copy();
|
||||
planeswalker.adjustCosts(copiedAbility, game);
|
||||
game.getContinuousEffects().costModification(copiedAbility, game);
|
||||
loyaltyCost = 0;
|
||||
for (Cost cost : copiedAbility.getCosts()) {
|
||||
if (cost instanceof PayLoyaltyCost) {
|
||||
loyaltyCost += ((PayLoyaltyCost) cost).getAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return planeswalker.getCounters(game).getCount(CounterType.LOYALTY) + loyaltyCost >= 0 && planeswalker.canLoyaltyBeUsed(game);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -43,7 +57,6 @@ public class PayLoyaltyCost extends CostImpl {
|
|||
* ability whose cost has you put loyalty counters on a planeswalker, the
|
||||
* number you put on isn't doubled. This is because those counters are put
|
||||
* on as a cost, not as an effect.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
|
|
@ -65,4 +78,16 @@ public class PayLoyaltyCost extends CostImpl {
|
|||
return new PayLoyaltyCost(this);
|
||||
}
|
||||
|
||||
public int getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(int amount) {
|
||||
this.amount = amount;
|
||||
|
||||
this.text = Integer.toString(this.amount);
|
||||
if (this.amount > 0) {
|
||||
this.text = '+' + this.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,27 @@
|
|||
|
||||
|
||||
package mage.abilities.costs.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.LoyaltyAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PayVariableLoyaltyCost extends VariableCostImpl {
|
||||
public class PayVariableLoyaltyCost extends VariableCostImpl {
|
||||
|
||||
// dynamic x cost modification from effects like Carth the Lion
|
||||
// GUI only (applies to -X value on X announce)
|
||||
// Example:
|
||||
// - counters: 3
|
||||
// - cost modification: +1
|
||||
// - max possible X to pay: 4
|
||||
private int costModification = 0;
|
||||
|
||||
public PayVariableLoyaltyCost() {
|
||||
super("loyality counters to remove");
|
||||
|
|
@ -23,17 +30,18 @@ public class PayVariableLoyaltyCost extends VariableCostImpl {
|
|||
|
||||
public PayVariableLoyaltyCost(final PayVariableLoyaltyCost cost) {
|
||||
super(cost);
|
||||
this.costModification = cost.costModification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayVariableLoyaltyCost copy() {
|
||||
return new PayVariableLoyaltyCost(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||
Permanent planeswalker = game.getPermanent(source.getSourceId());
|
||||
return planeswalker!= null && planeswalker.canLoyaltyBeUsed(game);
|
||||
return planeswalker != null && planeswalker.canLoyaltyBeUsed(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -43,12 +51,33 @@ public class PayVariableLoyaltyCost extends VariableCostImpl {
|
|||
|
||||
@Override
|
||||
public int getMaxValue(Ability source, Game game) {
|
||||
int maxValue = 0;
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
if (permanent != null) {
|
||||
maxValue = permanent.getCounters(game).getCount(CounterType.LOYALTY.getName());
|
||||
if (permanent == null) {
|
||||
return 0;
|
||||
}
|
||||
return maxValue;
|
||||
|
||||
int maxValue = permanent.getCounters(game).getCount(CounterType.LOYALTY.getName());
|
||||
|
||||
// apply cost modification
|
||||
if (source instanceof LoyaltyAbility) {
|
||||
LoyaltyAbility copiedAbility = ((LoyaltyAbility) source).copy();
|
||||
permanent.adjustCosts(copiedAbility, game);
|
||||
game.getContinuousEffects().costModification(copiedAbility, game);
|
||||
for (Cost cost : copiedAbility.getCosts()) {
|
||||
if (cost instanceof PayVariableLoyaltyCost) {
|
||||
maxValue += ((PayVariableLoyaltyCost) cost).getCostModification();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Math.max(0, maxValue);
|
||||
}
|
||||
|
||||
public int getCostModification() {
|
||||
return costModification;
|
||||
}
|
||||
|
||||
public void setCostModification(int costModification) {
|
||||
this.costModification = costModification;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue