mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
Merge pull request #13516 from magefree/cost-adjusters-rework
This commit is contained in:
commit
2a1eebc5fc
168 changed files with 1635 additions and 540 deletions
|
|
@ -1863,8 +1863,11 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
|
||||
@Override
|
||||
public int announceXMana(int min, int max, String message, Game game, Ability ability) {
|
||||
log.debug("announceXMana");
|
||||
//TODO: improve this
|
||||
// current logic - use max possible mana
|
||||
|
||||
// TODO: add good/bad effects support
|
||||
// TODO: add simple game simulations like declare blocker?
|
||||
|
||||
int numAvailable = getAvailableManaProducers(game).size() - ability.getManaCosts().manaValue();
|
||||
if (numAvailable < 0) {
|
||||
numAvailable = 0;
|
||||
|
|
@ -1881,12 +1884,17 @@ public class ComputerPlayer extends PlayerImpl {
|
|||
|
||||
@Override
|
||||
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variablCost) {
|
||||
log.debug("announceXCost");
|
||||
// current logic - use random non-zero value
|
||||
|
||||
// TODO: add good/bad effects support
|
||||
// TODO: remove random logic
|
||||
|
||||
int value = RandomUtil.nextInt(CardUtil.overflowInc(max, 1));
|
||||
if (value < min) {
|
||||
value = min;
|
||||
}
|
||||
if (value < max) {
|
||||
// do not use zero values
|
||||
value++;
|
||||
}
|
||||
return value;
|
||||
|
|
|
|||
|
|
@ -1709,6 +1709,8 @@ public class HumanPlayer extends PlayerImpl {
|
|||
if (response.getInteger() != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: add response verify here
|
||||
}
|
||||
|
||||
if (response.getInteger() != null) {
|
||||
|
|
|
|||
|
|
@ -62,9 +62,6 @@ hand:Human:Angelic Edict:3
|
|||
battlefield:Computer:Grizzly Bears:2
|
||||
battlefield:Human:Grizzly Bears:2
|
||||
|
||||
// special command, see SystemUtil for more special commands list
|
||||
[@activate opponent ability]
|
||||
|
||||
[diff set codes example]
|
||||
battlefield:Human:XLN-Island:1
|
||||
battlefield:Human:UST-Island:1
|
||||
|
|
|
|||
|
|
@ -1,43 +1,30 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.common.DiscardTargetCost;
|
||||
import mage.abilities.costs.costadjusters.DiscardXCardsCostAdjuster;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.effects.common.discard.LookTargetHandChooseDiscardEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author fireshoes
|
||||
* @author fireshoes, JayDi85
|
||||
*/
|
||||
public final class AbandonHope extends CardImpl {
|
||||
|
||||
public AbandonHope(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{1}{B}");
|
||||
|
||||
// As an additional cost to cast Abandon Hope, discard X cards.
|
||||
Ability ability = new SimpleStaticAbility(
|
||||
Zone.ALL, new InfoEffect("As an additional cost to cast this spell, discard X cards")
|
||||
);
|
||||
ability.setRuleAtTheTop(true);
|
||||
this.addAbility(ability);
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
DiscardXCardsCostAdjuster.addAdjusterAndMessage(this, StaticFilters.FILTER_CARD_CARDS);
|
||||
|
||||
// Look at target opponent's hand and choose X cards from it. That player discards those cards.
|
||||
this.getSpellAbility().addEffect(new LookTargetHandChooseDiscardEffect(false, GetXValue.instance, StaticFilters.FILTER_CARD_CARDS));
|
||||
this.getSpellAbility().addTarget(new TargetOpponent());
|
||||
this.getSpellAbility().setCostAdjuster(AbandonHopeAdjuster.instance);
|
||||
}
|
||||
|
||||
private AbandonHope(final AbandonHope card) {
|
||||
|
|
@ -48,16 +35,4 @@ public final class AbandonHope extends CardImpl {
|
|||
public AbandonHope copy() {
|
||||
return new AbandonHope(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum AbandonHopeAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
int xValue = CardUtil.getSourceCostsTag(game, ability, "X", 0);
|
||||
if (xValue > 0) {
|
||||
ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, StaticFilters.FILTER_CARD_CARDS)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ public final class AeonChronicler extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Aeon Chronicler's power and toughness are each equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY)));
|
||||
|
||||
// Suspend X-{X}{3}{U}. X can't be 0.
|
||||
this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl<>("{3}{U}"), this, true));
|
||||
|
|
|
|||
|
|
@ -1,27 +1,18 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.common.DiscardTargetCost;
|
||||
import mage.abilities.costs.costadjusters.DiscardXCardsCostAdjuster;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.targetadjustment.XTargetsCountAdjuster;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class AetherTide extends CardImpl {
|
||||
|
|
@ -29,10 +20,8 @@ public final class AetherTide extends CardImpl {
|
|||
public AetherTide(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}");
|
||||
|
||||
// As an additional cost to cast Aether Tide, discard X creature cards.
|
||||
Ability ability = new SimpleStaticAbility(Zone.ALL, new InfoEffect("As an additional cost to cast this spell, discard X creature cards"));
|
||||
ability.setRuleAtTheTop(true);
|
||||
this.addAbility(ability);
|
||||
// As an additional cost to cast this spell, discard X creature cards.
|
||||
DiscardXCardsCostAdjuster.addAdjusterAndMessage(this, StaticFilters.FILTER_CARD_CREATURES);
|
||||
|
||||
// Return X target creatures to their owners' hands.
|
||||
Effect effect = new ReturnToHandTargetEffect();
|
||||
|
|
@ -40,8 +29,6 @@ public final class AetherTide extends CardImpl {
|
|||
this.getSpellAbility().addEffect(effect);
|
||||
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
|
||||
this.getSpellAbility().setTargetAdjuster(new XTargetsCountAdjuster());
|
||||
this.getSpellAbility().setCostAdjuster(AetherTideCostAdjuster.instance);
|
||||
|
||||
}
|
||||
|
||||
private AetherTide(final AetherTide card) {
|
||||
|
|
@ -53,15 +40,3 @@ public final class AetherTide extends CardImpl {
|
|||
return new AetherTide(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum AetherTideCostAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
int xValue = CardUtil.getSourceCostsTag(game, ability, "X", 0);
|
||||
if (xValue > 0) {
|
||||
ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, StaticFilters.FILTER_CARD_CREATURES)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package mage.cards.a;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
|
|
@ -36,12 +36,8 @@ public final class AladdinsLamp extends CardImpl {
|
|||
// {X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0.
|
||||
Ability ability = new SimpleActivatedAbility(new AladdinsLampEffect(), new ManaCostsImpl<>("{X}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
for (Object cost : ability.getManaCosts()) {
|
||||
if (cost instanceof VariableManaCost) {
|
||||
((VariableManaCost) cost).setMinX(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ability.setCostAdjuster(AladdinsLampCostAdjuster.instance);
|
||||
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -101,3 +97,17 @@ class AladdinsLampEffect extends ReplacementEffectImpl {
|
|||
return source.isControlledBy(event.getPlayerId());
|
||||
}
|
||||
}
|
||||
|
||||
enum AladdinsLampCostAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void prepareX(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ability.setVariableCostsMinMax(1, Math.max(1, controller.getLibrary().size()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ public final class AlandraSkyDreamer extends CardImpl {
|
|||
// Whenever you draw your fifth card each turn, Alandra, Sky Dreamer and Drakes you control each get +X/+X until end of turn, where X is the number of cards in your hand.
|
||||
DrawNthCardTriggeredAbility drawNthCardTriggeredAbility = new DrawNthCardTriggeredAbility(
|
||||
new BoostSourceEffect(
|
||||
CardsInControllerHandCount.instance,
|
||||
CardsInControllerHandCount.instance,
|
||||
CardsInControllerHandCount.ANY,
|
||||
CardsInControllerHandCount.ANY,
|
||||
Duration.EndOfTurn
|
||||
).setText("{this}"),
|
||||
false,
|
||||
|
|
@ -56,8 +56,8 @@ public final class AlandraSkyDreamer extends CardImpl {
|
|||
);
|
||||
drawNthCardTriggeredAbility.addEffect(
|
||||
new BoostControlledEffect(
|
||||
CardsInControllerHandCount.instance,
|
||||
CardsInControllerHandCount.instance,
|
||||
CardsInControllerHandCount.ANY,
|
||||
CardsInControllerHandCount.ANY,
|
||||
Duration.EndOfTurn,
|
||||
filter,
|
||||
false
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class AncientExcavationEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
DynamicValue numCards = CardsInControllerHandCount.instance;
|
||||
DynamicValue numCards = CardsInControllerHandCount.ANY;
|
||||
int amount = numCards.calculate(game, source, this);
|
||||
int cardsDrawn = player.drawCards(amount, source, game);
|
||||
player.discard(cardsDrawn, false, false, source, game);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -26,7 +25,7 @@ public final class Archivist extends CardImpl {
|
|||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
//{T}: Draw a card.
|
||||
// {T}: Draw a card.
|
||||
this.addAbility(new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new TapSourceCost()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ enum ArmMountedAnchorAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
// checking state
|
||||
if (HeckbentCondition.instance.apply(game, ability)) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public final class BaldinCenturyHerdmaster extends CardImpl {
|
|||
|
||||
// Whenever Baldin, Century Herdmaster attacks, up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand.
|
||||
Ability ability = new AttacksTriggeredAbility(new BoostTargetEffect(
|
||||
StaticValue.get(0), CardsInControllerHandCount.instance, Duration.EndOfTurn
|
||||
StaticValue.get(0), CardsInControllerHandCount.ANY, Duration.EndOfTurn
|
||||
).setText("up to one hundred target creatures each get +0/+X until end of turn, where X is the number of cards in your hand"));
|
||||
ability.addTarget(new TargetCreaturePermanent(0, 100));
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -1,25 +1,28 @@
|
|||
package mage.cards.b;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.EarlyTargetCost;
|
||||
import mage.abilities.costs.VariableCostType;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author awjackson
|
||||
* @author awjackson, JayDi85
|
||||
*/
|
||||
public final class BargainingTable extends CardImpl {
|
||||
|
||||
|
|
@ -27,13 +30,10 @@ public final class BargainingTable extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||
|
||||
// {X}, {T}: Draw a card. X is the number of cards in an opponent's hand.
|
||||
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new ManaCostsImpl<>("{X}"));
|
||||
Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new BargainingTableXCost());
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addEffect(new InfoEffect("X is the number of cards in an opponent's hand"));
|
||||
// You choose an opponent on announcement. This is not targeted, but a choice is still made.
|
||||
// This choice is made before determining the value for X that is used in the cost. (2004-10-04)
|
||||
ability.addTarget(new TargetOpponent(true));
|
||||
ability.setCostAdjuster(BargainingTableAdjuster.instance);
|
||||
ability.setCostAdjuster(BargainingTableCostAdjuster.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -47,26 +47,70 @@ public final class BargainingTable extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum BargainingTableAdjuster implements CostAdjuster {
|
||||
class BargainingTableXCost extends VariableManaCost implements EarlyTargetCost {
|
||||
|
||||
// You choose an opponent on announcement. This is not targeted, but a choice is still made.
|
||||
// This choice is made before determining the value for X that is used in the cost.
|
||||
// (2004-10-04)
|
||||
|
||||
public BargainingTableXCost() {
|
||||
super(VariableCostType.NORMAL, 1);
|
||||
}
|
||||
|
||||
public BargainingTableXCost(final BargainingTableXCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chooseTarget(Game game, Ability source, Player controller) {
|
||||
Target targetOpponent = new TargetOpponent(true);
|
||||
controller.choose(Outcome.Benefit, targetOpponent, source, game);
|
||||
addTarget(targetOpponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BargainingTableXCost copy() {
|
||||
return new BargainingTableXCost(this);
|
||||
}
|
||||
}
|
||||
|
||||
enum BargainingTableCostAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
int handSize = Integer.MAX_VALUE;
|
||||
if (game.inCheckPlayableState()) {
|
||||
for (UUID playerId : CardUtil.getAllPossibleTargets(ability, game)) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
handSize = Math.min(handSize, player.getHand().size());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Player player = game.getPlayer(ability.getFirstTarget());
|
||||
if (player != null) {
|
||||
handSize = player.getHand().size();
|
||||
}
|
||||
public void prepareX(Ability ability, Game game) {
|
||||
// make sure early target used
|
||||
BargainingTableXCost cost = ability.getManaCostsToPay().getVariableCosts().stream()
|
||||
.filter(c -> c instanceof BargainingTableXCost)
|
||||
.map(c -> (BargainingTableXCost) c)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (cost == null) {
|
||||
throw new IllegalArgumentException("Wrong code usage: cost item lost");
|
||||
}
|
||||
|
||||
if (game.inCheckPlayableState()) {
|
||||
// possible X
|
||||
int minHandSize = game.getOpponents(ability.getControllerId(), true).stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.mapToInt(p -> p.getHand().size())
|
||||
.min()
|
||||
.orElse(0);
|
||||
int maxHandSize = game.getOpponents(ability.getControllerId(), true).stream()
|
||||
.map(game::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.mapToInt(p -> p.getHand().size())
|
||||
.max()
|
||||
.orElse(Integer.MAX_VALUE);
|
||||
ability.setVariableCostsMinMax(minHandSize, maxHandSize);
|
||||
} else {
|
||||
// real X
|
||||
Player opponent = game.getPlayer(cost.getTargets().getFirstTarget());
|
||||
if (opponent == null) {
|
||||
throw new IllegalStateException("Wrong code usage: cost target lost");
|
||||
}
|
||||
ability.setVariableCostsValue(opponent.getHand().size());
|
||||
}
|
||||
ability.clearManaCostsToPay();
|
||||
ability.addManaCostsToPay(new GenericManaCost(handSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,10 +19,7 @@ import mage.abilities.hint.ValueHint;
|
|||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
|
|
@ -116,7 +113,7 @@ enum BaruWurmspeakerAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
int value = BaruWurmspeakerValue.instance.calculate(game, ability, null);
|
||||
if (value > 0) {
|
||||
CardUtil.reduceCost(ability, value);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ enum BattlefieldButcherAdjuster implements CostAdjuster {
|
|||
private static final Hint hint = new ValueHint("Creature cards in your graveyard", xValue);
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
CardUtil.reduceCost(ability, xValue.calculate(game, ability, null));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,20 +3,21 @@ package mage.cards.b;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.common.continuous.SetBasePowerToughnessEnchantedEffect;
|
||||
import mage.abilities.keyword.EquipAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.constants.Outcome;
|
||||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
|
|
@ -35,7 +36,7 @@ public final class BeltOfGiantStrength extends CardImpl {
|
|||
// Equip {10}. This ability costs {X} less to activate where X is the power of the creature it targets.
|
||||
EquipAbility ability = new EquipAbility(Outcome.BoostCreature, new GenericManaCost(10), new TargetControlledCreaturePermanent(), false);
|
||||
ability.setCostReduceText("This ability costs {X} less to activate, where X is the power of the creature it targets.");
|
||||
ability.setCostAdjuster(BeltOfGiantStrengthAdjuster.instance);
|
||||
ability.setCostAdjuster(BeltOfGiantStrengthCostAdjuster.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -49,33 +50,23 @@ public final class BeltOfGiantStrength extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum BeltOfGiantStrengthAdjuster implements CostAdjuster {
|
||||
enum BeltOfGiantStrengthCostAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
int power;
|
||||
if (game.inCheckPlayableState()) {
|
||||
int maxPower = 0;
|
||||
for (UUID permId : CardUtil.getAllPossibleTargets(ability, game)) {
|
||||
Permanent permanent = game.getPermanent(permId);
|
||||
if (permanent != null) {
|
||||
int power = permanent.getPower().getValue();
|
||||
if (power > maxPower) {
|
||||
maxPower = power;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxPower > 0) {
|
||||
CardUtil.reduceCost(ability, maxPower);
|
||||
}
|
||||
power = CardUtil.getAllPossibleTargets(ability, game).stream()
|
||||
.map(game::getPermanent)
|
||||
.filter(Objects::nonNull)
|
||||
.mapToInt(p -> p.getPower().getValue())
|
||||
.max().orElse(0);
|
||||
} else {
|
||||
Permanent permanent = game.getPermanent(ability.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
int power = permanent.getPower().getValue();
|
||||
if (power > 0) {
|
||||
CardUtil.reduceCost(ability, power);
|
||||
}
|
||||
}
|
||||
power = Optional.ofNullable(game.getPermanent(ability.getFirstTarget()))
|
||||
.map(p -> p.getPower().getValue())
|
||||
.orElse(0);
|
||||
}
|
||||
CardUtil.reduceCost(ability, power);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ enum BiteDownOnCrimeAdjuster implements CostAdjuster {
|
|||
private static final OptionalAdditionalCost collectEvidenceCost = CollectEvidenceAbility.makeCost(6);
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (CollectedEvidenceCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && collectEvidenceCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public final class BodyOfKnowledge extends CardImpl {
|
|||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL,
|
||||
new SetBasePowerToughnessSourceEffect(
|
||||
CardsInControllerHandCount.instance
|
||||
CardsInControllerHandCount.ANY
|
||||
)
|
||||
));
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ enum CallerOfTheHuntAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void prepareCost(Ability ability, Game game) {
|
||||
if (game.inCheckPlayableState()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -103,6 +103,7 @@ enum CallerOfTheHuntAdjuster implements CostAdjuster {
|
|||
game.getState().setValue(sourceObject.getId() + "_type", maxSubType);
|
||||
} else {
|
||||
// human choose
|
||||
// TODO: need early target cost instead dialog here
|
||||
Effect effect = new ChooseCreatureTypeEffect(Outcome.Benefit);
|
||||
effect.apply(game, ability);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import java.util.UUID;
|
|||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.triggers.BeginningOfCombatTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
|
|
@ -130,7 +131,7 @@ enum CaptainAmericaFirstAvengerValue implements DynamicValue {
|
|||
}
|
||||
}
|
||||
|
||||
class CaptainAmericaFirstAvengerUnattachCost extends EarlyTargetCost {
|
||||
class CaptainAmericaFirstAvengerUnattachCost extends CostImpl implements EarlyTargetCost {
|
||||
|
||||
private static final FilterPermanent filter = new FilterEquipmentPermanent("equipment attached to this creature");
|
||||
private static final FilterPermanent subfilter = new FilterControlledPermanent("{this}");
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public final class CastleLocthwain extends CardImpl {
|
|||
Ability ability = new SimpleActivatedAbility(
|
||||
new DrawCardSourceControllerEffect(1).setText("draw a card,"), new ManaCostsImpl<>("{1}{B}{B}")
|
||||
);
|
||||
ability.addEffect(new LoseLifeSourceControllerEffect(CardsInControllerHandCount.instance)
|
||||
ability.addEffect(new LoseLifeSourceControllerEffect(CardsInControllerHandCount.ANY)
|
||||
.setText("then you lose life equal to the number of cards in your hand"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public final class ChanneledForce extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{R}");
|
||||
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS));
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||
|
||||
// Target player draws X cards. Channeled Force deals X damage to up to one target creature or planeswalker.
|
||||
this.getSpellAbility().addEffect(new ChanneledForceEffect());
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ enum CrownOfGondorAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (MonarchIsSourceControllerCondition.instance.apply(game, ability)) {
|
||||
CardUtil.reduceCost(ability, 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
|
|
@ -59,7 +58,7 @@ public final class DamiaSageOfStone extends CardImpl {
|
|||
class DamiaSageOfStoneTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
|
||||
|
||||
DamiaSageOfStoneTriggeredAbility() {
|
||||
super(TargetController.YOU, new DrawCardSourceControllerEffect(new IntPlusDynamicValue(7, new MultipliedValue(CardsInControllerHandCount.instance, -1))), false);
|
||||
super(TargetController.YOU, new DrawCardSourceControllerEffect(new IntPlusDynamicValue(7, new MultipliedValue(CardsInControllerHandCount.ANY, -1))), false);
|
||||
}
|
||||
|
||||
private DamiaSageOfStoneTriggeredAbility(final DamiaSageOfStoneTriggeredAbility ability) {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ enum DeepwoodDenizenAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
CardUtil.reduceCost(ability, DeepwoodDenizenValue.instance.calculate(game, ability, null));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import java.util.UUID;
|
|||
*/
|
||||
public final class DemonicLore extends CardImpl {
|
||||
|
||||
private static final DynamicValue xValue = new MultipliedValue(CardsInControllerHandCount.instance, 2);
|
||||
private static final DynamicValue xValue = new MultipliedValue(CardsInControllerHandCount.ANY, 2);
|
||||
|
||||
public DemonicLore(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -28,7 +27,7 @@ public final class DescendantOfSoramaro extends CardImpl {
|
|||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(3);
|
||||
// {1}{U}: Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order.
|
||||
Effect effect = new LookLibraryControllerEffect(CardsInControllerHandCount.instance);
|
||||
Effect effect = new LookLibraryControllerEffect(CardsInControllerHandCount.ANY);
|
||||
effect.setText("Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order");
|
||||
this.addAbility(new SimpleActivatedAbility(
|
||||
effect, new ManaCostsImpl<>("{1}{U}")));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import mage.abilities.costs.Cost;
|
|||
import mage.abilities.costs.VariableCostImpl;
|
||||
import mage.abilities.costs.VariableCostType;
|
||||
import mage.abilities.costs.common.DiscardTargetCost;
|
||||
import mage.abilities.costs.common.DiscardXTargetCost;
|
||||
import mage.abilities.costs.costadjusters.DiscardXCardsCostAdjuster;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.common.DamageAllEffect;
|
||||
import mage.abilities.effects.common.SacrificeAllEffect;
|
||||
|
|
@ -12,6 +14,7 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledLandPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
|
|
@ -28,8 +31,8 @@ public final class DevastatingDreams extends CardImpl {
|
|||
public DevastatingDreams(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}{R}");
|
||||
|
||||
// As an additional cost to cast Devastating Dreams, discard X cards at random.
|
||||
this.getSpellAbility().addCost(new DevastatingDreamsAdditionalCost());
|
||||
// As an additional cost to cast this spell, discard X cards at random.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true).withRandom());
|
||||
|
||||
// Each player sacrifices X lands.
|
||||
this.getSpellAbility().addEffect(new SacrificeAllEffect(GetXValue.instance, new FilterControlledLandPermanent("lands")));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public final class DivinersPortent extends CardImpl {
|
|||
// Roll a d20 and add the number of cards in your hand.
|
||||
RollDieWithResultTableEffect effect = new RollDieWithResultTableEffect(
|
||||
20, "roll a d20 and add the number " +
|
||||
"of cards in your hand", CardsInControllerHandCount.instance, 0
|
||||
"of cards in your hand", CardsInControllerHandCount.ANY, 0
|
||||
);
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -32,7 +31,7 @@ public final class DreadSlag extends CardImpl {
|
|||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
// Dread Slag gets -4/-4 for each card in your hand.
|
||||
DynamicValue amount = new MultipliedValue(CardsInControllerHandCount.instance, -4);
|
||||
DynamicValue amount = new MultipliedValue(CardsInControllerHandCount.ANY, -4);
|
||||
Effect effect = new BoostSourceEffect(amount, amount, Duration.WhileOnBattlefield);
|
||||
effect.setText("{this} gets -4/-4 for each card in your hand");
|
||||
this.addAbility(new SimpleStaticAbility(effect));
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public final class DugganPrivateDetective extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Duggan's power and toughness are each equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY)));
|
||||
|
||||
// Whenever Duggan enters the battlefield or attacks, investigate.
|
||||
this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new InvestigateEffect().setText("investigate")));
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.costs.costadjusters.ImprintedManaValueXCostAdjuster;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -23,7 +24,6 @@ import mage.players.Player;
|
|||
import mage.target.TargetCard;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ApprovingObject;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
|
|
@ -44,7 +44,7 @@ public final class EliteArcanist extends CardImpl {
|
|||
// {X}, {T}: Copy the exiled card. You may cast the copy without paying its mana cost. X is the converted mana cost of the exiled card.
|
||||
Ability ability = new SimpleActivatedAbility(new EliteArcanistCopyEffect(), new ManaCostsImpl<>("{X}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.setCostAdjuster(EliteArcanistAdjuster.instance);
|
||||
ability.setCostAdjuster(ImprintedManaValueXCostAdjuster.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -58,29 +58,6 @@ public final class EliteArcanist extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum EliteArcanistAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
|
||||
if (sourcePermanent == null
|
||||
|| sourcePermanent.getImprinted() == null
|
||||
|| sourcePermanent.getImprinted().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Card imprintedInstant = game.getCard(sourcePermanent.getImprinted().get(0));
|
||||
if (imprintedInstant == null) {
|
||||
return;
|
||||
}
|
||||
int cmc = imprintedInstant.getManaValue();
|
||||
if (cmc > 0) {
|
||||
ability.clearManaCostsToPay();
|
||||
ability.addManaCostsToPay(new GenericManaCost(cmc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EliteArcanistImprintEffect extends OneShotEffect {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("instant card from your hand");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
|
|
@ -38,7 +37,7 @@ public final class EmpyrialArmor extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
|
||||
// Enchanted creature gets +1/+1 for each card in your hand.
|
||||
DynamicValue xValue = CardsInControllerHandCount.instance;
|
||||
DynamicValue xValue = CardsInControllerHandCount.ANY;
|
||||
this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(xValue, xValue, Duration.WhileOnBattlefield)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -25,7 +24,7 @@ public final class EmpyrialPlate extends CardImpl {
|
|||
this.subtype.add(SubType.EQUIPMENT);
|
||||
|
||||
// Equipped creature gets +1/+1 for each card in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(CardsInControllerHandCount.instance, CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(CardsInControllerHandCount.ANY, CardsInControllerHandCount.ANY)));
|
||||
|
||||
// Equip {2}
|
||||
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2), false));
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public final class EndlessSwarm extends CardImpl {
|
|||
|
||||
|
||||
// Create a 1/1 green Snake creature token for each card in your hand.
|
||||
this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), CardsInControllerHandCount.instance).setText("create a 1/1 green Snake creature token for each card in your hand"));
|
||||
this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), CardsInControllerHandCount.ANY).setText("create a 1/1 green Snake creature token for each card in your hand"));
|
||||
|
||||
// Epic
|
||||
this.getSpellAbility().addEffect(new EpicEffect());
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ enum EsquireOfTheKingAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (game.getBattlefield().contains(StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY, ability, game, 1)) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,8 +80,7 @@ enum EtheriumPteramanderAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
int count = artifactCount.calculate(game, ability, null);
|
||||
CardUtil.reduceCost(ability, count);
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
CardUtil.reduceCost(ability, artifactCount.calculate(game, ability, null));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public final class FatefulShowdown extends CardImpl {
|
|||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{R}");
|
||||
|
||||
// Fateful Showdown deals damage to any target equal to the number of cards in your hand. Discard all the cards in your hand, then draw that many cards.
|
||||
Effect effect = new DamageTargetEffect(CardsInControllerHandCount.instance);
|
||||
Effect effect = new DamageTargetEffect(CardsInControllerHandCount.ANY);
|
||||
effect.setText("{this} deals damage to any target equal to the number of cards in your hand");
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
this.getSpellAbility().addTarget(new TargetAnyTarget());
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ package mage.cards.f;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.CostModificationType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
@ -24,8 +24,8 @@ public final class Fireball extends CardImpl {
|
|||
public Fireball(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}");
|
||||
|
||||
// Fireball deals X damage divided evenly, rounded down, among any number of target creatures and/or players.
|
||||
// Fireball costs 1 more to cast for each target beyond the first.
|
||||
// This spell costs {1} more to cast for each target beyond the first.
|
||||
// Fireball deals X damage divided evenly, rounded down, among any number of targets.
|
||||
this.getSpellAbility().addTarget(new FireballTargetCreatureOrPlayer(0, Integer.MAX_VALUE));
|
||||
this.getSpellAbility().addEffect(new FireballEffect());
|
||||
this.getSpellAbility().setCostAdjuster(FireballAdjuster.instance);
|
||||
|
|
@ -45,10 +45,10 @@ enum FireballAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void increaseCost(Ability ability, Game game) {
|
||||
int numTargets = ability.getTargets().isEmpty() ? 0 : ability.getTargets().get(0).getTargets().size();
|
||||
if (numTargets > 1) {
|
||||
ability.addManaCostsToPay(new GenericManaCost(numTargets - 1));
|
||||
CardUtil.increaseCost(ability, numTargets - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public final class FiresOfVictory extends CardImpl {
|
|||
KickedCondition.ONCE,
|
||||
"If this spell was kicked, draw a card."
|
||||
));
|
||||
this.getSpellAbility().addEffect(new DamageTargetEffect(CardsInControllerHandCount.instance)
|
||||
this.getSpellAbility().addEffect(new DamageTargetEffect(CardsInControllerHandCount.ANY)
|
||||
.setText("{this} deals damage to target creature or planeswalker equal to the number of cards in your hand."));
|
||||
this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
|
|
@ -25,8 +26,8 @@ public final class Firestorm extends CardImpl {
|
|||
public Firestorm(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
|
||||
|
||||
// As an additional cost to cast Firestorm, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true));
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||
|
||||
// Firestorm deals X damage to each of X target creatures and/or players.
|
||||
this.getSpellAbility().addEffect(new FirestormEffect());
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ enum FugitiveCodebreakerAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
CardUtil.reduceCost(ability, FugitiveCodebreakerDisguiseAbility.xValue.calculate(game, ability, null));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
|
|
@ -42,7 +41,7 @@ public final class GeralfsMasterpiece extends CardImpl {
|
|||
this.addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Geralf's Masterpiece gets -1/-1 for each card in your hand.
|
||||
DynamicValue count = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
|
||||
DynamicValue count = new SignInversionDynamicValue(CardsInControllerHandCount.ANY);
|
||||
Effect effect = new BoostSourceEffect(count, count, Duration.WhileOnBattlefield);
|
||||
effect.setText("{this} gets -1/-1 for each card in your hand");
|
||||
this.addAbility(new SimpleStaticAbility(effect));
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public final class GerrardsWisdom extends CardImpl {
|
|||
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}{W}");
|
||||
|
||||
// You gain 2 life for each card in your hand.
|
||||
this.getSpellAbility().addEffect(new GainLifeEffect(new MultipliedValue(CardsInControllerHandCount.instance, 2),
|
||||
this.getSpellAbility().addEffect(new GainLifeEffect(new MultipliedValue(CardsInControllerHandCount.ANY, 2),
|
||||
"You gain 2 life for each card in your hand"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ enum GhostfireBladeAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
// checking state
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (game.inCheckPlayableState()) {
|
||||
// possible
|
||||
if (CardUtil
|
||||
.getAllPossibleTargets(ability, game)
|
||||
.stream()
|
||||
|
|
@ -67,6 +67,7 @@ enum GhostfireBladeAdjuster implements CostAdjuster {
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
// real
|
||||
Permanent permanent = game.getPermanent(ability.getFirstTarget());
|
||||
if (permanent == null || !permanent.getColor(game).isColorless()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ enum GrimGiganotosaurusAdjuster implements CostAdjuster {
|
|||
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller != null) {
|
||||
CardUtil.reduceCost(ability, xValue.calculate(game, ability, null));
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -29,7 +28,7 @@ public final class GrimStrider extends CardImpl {
|
|||
this.toughness = new MageInt(6);
|
||||
|
||||
// Grim Strider gets -1/-1 for each card in your hand.
|
||||
DynamicValue count = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
|
||||
DynamicValue count = new SignInversionDynamicValue(CardsInControllerHandCount.ANY);
|
||||
Effect effect = new BoostSourceEffect(count, count, Duration.WhileOnBattlefield);
|
||||
effect.setText("{this} gets -1/-1 for each card in your hand");
|
||||
this.addAbility(new SimpleStaticAbility(effect));
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ enum HamletGluttonAdjuster implements CostAdjuster {
|
|||
private static OptionalAdditionalCost bargainCost = BargainAbility.makeBargainCost();
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (BargainedCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && bargainCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public final class HandOfVecna extends CardImpl {
|
|||
this.addAbility(new EquipAbility(
|
||||
Outcome.Benefit,
|
||||
new PayLifeCost(
|
||||
CardsInControllerHandCount.instance, "1 life for each card in your hand"),
|
||||
CardsInControllerHandCount.ANY, "1 life for each card in your hand"),
|
||||
false
|
||||
));
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ package mage.cards.h;
|
|||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.VariableCostType;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
|
|
@ -29,9 +28,8 @@ public final class HelmOfObedience extends CardImpl {
|
|||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
|
||||
|
||||
// {X}, {T}: Target opponent puts cards from the top of their library into their graveyard until a creature card or X cards are put into that graveyard this way, whichever comes first. If a creature card is put into that graveyard this way, sacrifice Helm of Obedience and put that card onto the battlefield under your control. X can't be 0.
|
||||
VariableManaCost xCosts = new VariableManaCost(VariableCostType.NORMAL);
|
||||
xCosts.setMinX(1);
|
||||
Ability ability = new SimpleActivatedAbility(new HelmOfObedienceEffect(), xCosts);
|
||||
Ability ability = new SimpleActivatedAbility(new HelmOfObedienceEffect(), new ManaCostsImpl<>("{X}"));
|
||||
ability.setVariableCostsMinMax(1, Integer.MAX_VALUE);
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetOpponent());
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ final class HinataDawnCrownedEffectUtility
|
|||
public static int getTargetCount(Game game, Ability abilityToModify)
|
||||
{
|
||||
if (game.inCheckPlayableState()) {
|
||||
abilityToModify.getTargets().stream()
|
||||
.mapToInt(a -> !a.isRequired() ? 0 : a.getMinNumberOfTargets())
|
||||
.min()
|
||||
.orElse(0);
|
||||
Optional<Integer> max = abilityToModify.getTargets().stream().map(x -> x.getMaxNumberOfTargets()).max(Integer::compare);
|
||||
int allPossibleSize = CardUtil.getAllPossibleTargets(abilityToModify, game).size();
|
||||
return max.isPresent() ?
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ enum HurkylsFinalMeditationAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void increaseCost(Ability ability, Game game) {
|
||||
if (!game.isActivePlayer(ability.getControllerId())) {
|
||||
CardUtil.increaseCost(ability, 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ enum HyldasCrownOfWinterAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (ability.getControllerId().equals(game.getActivePlayerId())) {
|
||||
CardUtil.reduceCost(ability, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ enum IceOutAdjuster implements CostAdjuster {
|
|||
private static OptionalAdditionalCost bargainCost = BargainAbility.makeBargainCost();
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (BargainedCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && bargainCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 1);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public final class InnerCalmOuterStrength extends CardImpl {
|
|||
this.subtype.add(SubType.ARCANE);
|
||||
|
||||
// Target creature gets +X/+X until end of turn, where X is the number of cards in your hand.
|
||||
DynamicValue xValue= CardsInControllerHandCount.instance;
|
||||
DynamicValue xValue= CardsInControllerHandCount.ANY;
|
||||
Effect effect = new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn);
|
||||
effect.setText("Target creature gets +X/+X until end of turn, where X is the number of cards in your hand");
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public final class InnerFire extends CardImpl {
|
|||
|
||||
|
||||
// Add {R} for each card in your hand.
|
||||
this.getSpellAbility().addEffect(new DynamicManaEffect(Mana.RedMana(1), CardsInControllerHandCount.instance));
|
||||
this.getSpellAbility().addEffect(new DynamicManaEffect(Mana.RedMana(1), CardsInControllerHandCount.ANY));
|
||||
}
|
||||
|
||||
private InnerFire(final InnerFire card) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public final class InsidiousDreams extends CardImpl {
|
|||
public InsidiousDreams(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B}");
|
||||
|
||||
// As an additional cost to cast Insidious Dreams, discard X cards.
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||
|
||||
// Search your library for X cards. Then shuffle your library and put those cards on top of it in any order.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ enum JohannsStopgapAdjuster implements CostAdjuster {
|
|||
private static OptionalAdditionalCost bargainCost = BargainAbility.makeBargainCost();
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (BargainedCondition.instance.apply(game, ability)
|
||||
|| (game.inCheckPlayableState() && bargainCost.canPay(ability, null, ability.getControllerId(), game))) {
|
||||
CardUtil.reduceCost(ability, 2);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public final class JolraelMwonvuliRecluse extends CardImpl {
|
|||
|
||||
// {4}{G}{G}: Until end of turn, creatures you control have base power and toughness X/X, where X is the number of cards in your hand.
|
||||
this.addAbility(new SimpleActivatedAbility(new SetBasePowerToughnessAllEffect(
|
||||
CardsInControllerHandCount.instance, CardsInControllerHandCount.instance,
|
||||
CardsInControllerHandCount.ANY, CardsInControllerHandCount.ANY,
|
||||
Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURES
|
||||
).setText("until end of turn, creatures you control have base power and toughness X/X, " +
|
||||
"where X is the number of cards in your hand"), new ManaCostsImpl<>("{4}{G}{G}")));
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.token.TokenImpl;
|
||||
import mage.target.TargetPlayer;
|
||||
|
||||
|
|
@ -70,7 +69,7 @@ class TomoyaTheRevealer extends TokenImpl {
|
|||
toughness = new MageInt(3);
|
||||
|
||||
// {3}{U}{U},{T} : Target player draws X cards, where X is the number of cards in your hand.
|
||||
Ability ability = new SimpleActivatedAbility(new DrawCardTargetEffect(CardsInControllerHandCount.instance), new ManaCostsImpl<>("{3}{U}{U}"));
|
||||
Ability ability = new SimpleActivatedAbility(new DrawCardTargetEffect(CardsInControllerHandCount.ANY), new ManaCostsImpl<>("{3}{U}{U}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addTarget(new TargetPlayer());
|
||||
this.addAbility(ability);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public final class KagemaroFirstToSuffer extends CardImpl {
|
|||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
|
||||
DynamicValue xValue = CardsInControllerHandCount.instance;
|
||||
DynamicValue xValue = CardsInControllerHandCount.ANY;
|
||||
// Kagemaro, First to Suffer's power and toughness are each equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(xValue)));
|
||||
// {B}, Sacrifice Kagemaro: All creatures get -X/-X until end of turn, where X is the number of cards in your hand.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import mage.constants.CardType;
|
|||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
|
|
@ -40,7 +39,7 @@ public final class KagemarosClutch extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
|
||||
// Enchanted creature gets -X/-X, where X is the number of cards in your hand.
|
||||
DynamicValue xMinusValue = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
|
||||
DynamicValue xMinusValue = new SignInversionDynamicValue(CardsInControllerHandCount.ANY);
|
||||
Effect effect = new BoostEnchantedEffect(xMinusValue, xMinusValue, Duration.WhileOnBattlefield);
|
||||
effect.setText("Enchanted creature gets -X/-X, where X is the number of cards in your hand");
|
||||
this.addAbility(new SimpleStaticAbility(effect));
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ enum KamiOfJealousThirstAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void increaseCost(Ability ability, Game game) {
|
||||
int amount = CardsDrawnThisTurnDynamicValue.instance.calculate(game, ability, null);
|
||||
if (amount >= 3) {
|
||||
CardUtil.adjustCost(ability, new ManaCostsImpl<>("{4}{B}"), false);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -30,7 +29,7 @@ public final class KitsuneLoreweaver extends CardImpl {
|
|||
this.toughness = new MageInt(1);
|
||||
|
||||
// {1}{W}: Kitsune Loreweaver gets +0/+X until end of turn, where X is the number of cards in your hand.
|
||||
Effect effect = new BoostSourceEffect(StaticValue.get(0), CardsInControllerHandCount.instance, Duration.EndOfTurn);
|
||||
Effect effect = new BoostSourceEffect(StaticValue.get(0), CardsInControllerHandCount.ANY, Duration.EndOfTurn);
|
||||
effect.setText("{this} gets +0/+X until end of turn, where X is the number of cards in your hand");
|
||||
this.addAbility(new SimpleActivatedAbility(effect, new ManaCostsImpl<>("{1}{W}")));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public final class KiyomaroFirstToStand extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Kiyomaro, First to Stand's power and toughness are each equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY)));
|
||||
|
||||
// As long as you have four or more cards in hand, Kiyomaro has vigilance.
|
||||
Condition condition = new CardsInHandCondition(ComparisonType.MORE_THAN, 3);
|
||||
|
|
|
|||
|
|
@ -1,40 +1,43 @@
|
|||
package mage.cards.k;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.common.DiscardTargetCost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
import mage.abilities.costs.EarlyTargetCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.effects.common.DamageTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetAnyTarget;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author anonymous
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class KnollspineInvocation extends CardImpl {
|
||||
|
||||
private static final FilterCard filter = new FilterCard("a card with mana value X");
|
||||
protected static final FilterCard filter = new FilterCard("a card with mana value X");
|
||||
|
||||
public KnollspineInvocation(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{R}");
|
||||
|
||||
// {X}, Discard a card with converted mana cost X: Knollspine Invocation deals X damage to any target.
|
||||
// {X}, Discard a card with mana value X: This enchantment deals X damage to any target.
|
||||
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(GetXValue.instance, true), new ManaCostsImpl<>("{X}"));
|
||||
ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter)));
|
||||
ability.addCost(new KnollspineInvocationDiscardCost());
|
||||
ability.addTarget(new TargetAnyTarget());
|
||||
ability.setCostAdjuster(KnollspineInvocationAdjuster.instance);
|
||||
this.addAbility(ability);
|
||||
|
|
@ -50,22 +53,103 @@ public final class KnollspineInvocation extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
class KnollspineInvocationDiscardCost extends CostImpl implements EarlyTargetCost {
|
||||
|
||||
// discard card with early target selection, so {X} mana cost can be setup after choose
|
||||
|
||||
public KnollspineInvocationDiscardCost() {
|
||||
super();
|
||||
this.text = "Discard a card with mana value X";
|
||||
}
|
||||
|
||||
public KnollspineInvocationDiscardCost(final KnollspineInvocationDiscardCost cost) {
|
||||
super(cost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KnollspineInvocationDiscardCost copy() {
|
||||
return new KnollspineInvocationDiscardCost(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chooseTarget(Game game, Ability source, Player controller) {
|
||||
Target target = new TargetCardInHand().withChooseHint("to discard with mana value for X");
|
||||
controller.choose(Outcome.Discard, target, source, game);
|
||||
addTarget(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPay(Ability ability, Ability source, UUID controllerId, Game game) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
return controller != null && !controller.getHand().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pay(Ability ability, Game game, Ability source, UUID controllerId, boolean noMana, Cost costToPay) {
|
||||
this.paid = false;
|
||||
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Card card = controller.getHand().get(this.getTargets().getFirstTarget(), game);
|
||||
if (card == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.paid = controller.discard(card, true, source, game);
|
||||
|
||||
return this.paid;
|
||||
}
|
||||
}
|
||||
|
||||
enum KnollspineInvocationAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
int xValue = CardUtil.getSourceCostsTag(game, ability, "X", 0);
|
||||
for (Cost cost : ability.getCosts()) {
|
||||
if (!(cost instanceof DiscardTargetCost)) {
|
||||
continue;
|
||||
}
|
||||
DiscardTargetCost discardCost = (DiscardTargetCost) cost;
|
||||
discardCost.getTargets().clear();
|
||||
FilterCard adjustedFilter = new FilterCard("a card with mana value X");
|
||||
adjustedFilter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, xValue));
|
||||
discardCost.addTarget(new TargetCardInHand(adjustedFilter));
|
||||
public void prepareX(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure early target used
|
||||
VariableManaCost costX = ability.getManaCostsToPay().stream()
|
||||
.filter(c -> c instanceof VariableManaCost)
|
||||
.map(c -> (VariableManaCost) c)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (costX == null) {
|
||||
throw new IllegalArgumentException("Wrong code usage: costX lost");
|
||||
}
|
||||
KnollspineInvocationDiscardCost costDiscard = ability.getCosts().stream()
|
||||
.filter(c -> c instanceof KnollspineInvocationDiscardCost)
|
||||
.map(c -> (KnollspineInvocationDiscardCost) c)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (costDiscard == null) {
|
||||
throw new IllegalArgumentException("Wrong code usage: costDiscard lost");
|
||||
}
|
||||
|
||||
if (game.inCheckPlayableState()) {
|
||||
// possible X
|
||||
int minManaValue = controller.getHand().getCards(game).stream()
|
||||
.mapToInt(MageObject::getManaValue)
|
||||
.min()
|
||||
.orElse(0);
|
||||
int maxManaValue = controller.getHand().getCards(game).stream()
|
||||
.mapToInt(MageObject::getManaValue)
|
||||
.max()
|
||||
.orElse(0);
|
||||
ability.setVariableCostsMinMax(minManaValue, maxManaValue);
|
||||
} else {
|
||||
// real X
|
||||
Card card = controller.getHand().get(costDiscard.getTargets().getFirstTarget(), game);
|
||||
if (card == null) {
|
||||
throw new IllegalStateException("Wrong code usage: card to discard lost");
|
||||
}
|
||||
ability.setVariableCostsValue(card.getManaValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public final class LeonardoDaVinci extends CardImpl {
|
|||
this.power = new MageInt(3);
|
||||
this.toughness = new MageInt(3);
|
||||
|
||||
DynamicValue xValue = CardsInControllerHandCount.instance;
|
||||
DynamicValue xValue = CardsInControllerHandCount.ANY;
|
||||
// {3}{U}{U}: Until end of turn, Thopters you control have base power and toughness X/X, where X is the number of cards in your hand.
|
||||
this.addAbility(new SimpleActivatedAbility(new BoostControlledEffect(xValue, xValue, Duration.EndOfTurn, filter, false).setText(
|
||||
"Until end of turn, Thopters you control have base power and toughness X/X, where X is the number of cards in your hand."
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ enum LoreseekersStoneAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void increaseCost(Ability ability, Game game) {
|
||||
Player player = game.getPlayer(ability.getControllerId());
|
||||
if (player != null) {
|
||||
CardUtil.increaseCost(ability, player.getHand().size());
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class HighestLifeTotalAmongOpponentsCount implements DynamicValue {
|
|||
|
||||
@Override
|
||||
public DynamicValue copy() {
|
||||
return CardsInControllerHandCount.instance;
|
||||
return CardsInControllerHandCount.ANY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public final class ManifestationSage extends CardImpl {
|
|||
|
||||
// When Manifestation Sage enters the battlefield, create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it, where X is the number of cards in your hand.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(FractalToken.getEffect(
|
||||
CardsInControllerHandCount.instance, "Put X +1/+1 counters on it, " +
|
||||
CardsInControllerHandCount.ANY, "Put X +1/+1 counters on it, " +
|
||||
"where X is the number of cards in your hand"
|
||||
)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ enum MariposaMilitaryBaseAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
CardUtil.reduceCost(ability, SourceControllerCountersCount.RAD.calculate(game, ability, null));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public final class Maro extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Maro's power and toughness are each equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY)));
|
||||
}
|
||||
|
||||
private Maro(final Maro card) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public final class MasterTheWay extends CardImpl {
|
|||
|
||||
// Draw a card. Master the Way deals damage to any target equal to the number of cards in your hand.
|
||||
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
|
||||
Effect effect = new DamageTargetEffect(CardsInControllerHandCount.instance);
|
||||
Effect effect = new DamageTargetEffect(CardsInControllerHandCount.ANY);
|
||||
effect.setText("{this} deals damage to any target equal to the number of cards in your hand");
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
this.getSpellAbility().addTarget(new TargetAnyTarget());
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public final class MasumaroFirstToLive extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Masumaro, First to Live's power and toughness are each equal to twice the number of cards in your hand.
|
||||
DynamicValue xValue= new MultipliedValue(CardsInControllerHandCount.instance, 2);
|
||||
DynamicValue xValue= new MultipliedValue(CardsInControllerHandCount.ANY, 2);
|
||||
Effect effect = new SetBasePowerToughnessSourceEffect(xValue);
|
||||
effect.setText("{this}'s power and toughness are each equal to twice the number of cards in your hand");
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, effect));
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import mage.cards.CardSetInfo;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
|
||||
/**
|
||||
|
|
@ -26,7 +25,7 @@ public final class MeishinTheMindCage extends CardImpl {
|
|||
this.supertype.add(SuperType.LEGENDARY);
|
||||
|
||||
// All creatures get -X/-0, where X is the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(new BoostAllEffect(new SignInversionDynamicValue(CardsInControllerHandCount.instance), StaticValue.get(0), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, false, "All creatures get -X/-0, where X is the number of cards in your hand")));
|
||||
this.addAbility(new SimpleStaticAbility(new BoostAllEffect(new SignInversionDynamicValue(CardsInControllerHandCount.ANY), StaticValue.get(0), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, false, "All creatures get -X/-0, where X is the number of cards in your hand")));
|
||||
}
|
||||
|
||||
private MeishinTheMindCage(final MeishinTheMindCage card) {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public final class MinasTirithGarrison extends CardImpl {
|
|||
|
||||
// Minas Tirith Garrison's power is equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL, new SetBasePowerSourceEffect(CardsInControllerHandCount.instance)
|
||||
Zone.ALL, new SetBasePowerSourceEffect(CardsInControllerHandCount.ANY)
|
||||
));
|
||||
|
||||
// Whenever Minas Tirith Garrison attacks, you may tap any number of untapped Humans you control. Draw a card for each Human tapped this way.
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ enum MirrorOfGaladrielAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
int value = game.getBattlefield().count(
|
||||
StaticFilters.FILTER_CONTROLLED_CREATURE_LEGENDARY,
|
||||
ability.getControllerId(), ability, game
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ enum MobilizedDistrictAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller != null) {
|
||||
int count = cardsCount.calculate(game, ability, null);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.target.common.TargetCreatureOrPlaneswalker;
|
||||
import mage.target.targetadjustment.XTargetsCountAdjuster;
|
||||
|
||||
|
|
@ -21,8 +22,8 @@ public final class NahirisWrath extends CardImpl {
|
|||
public NahirisWrath(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
|
||||
|
||||
// As an additional cost to cast Nahiri's Wrath, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true));
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||
|
||||
// Nahiri's Wrath deals damage equal to the total converted mana cost of the discarded cards to each of up to X target creatures and/or planeswalkers.
|
||||
Effect effect = new DamageTargetEffect(DiscardCostCardManaValue.instance);
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ import mage.abilities.Ability;
|
|||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.common.ExileFromGraveCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.dynamicvalue.DynamicValue;
|
||||
import mage.abilities.dynamicvalue.common.GetXValue;
|
||||
import mage.abilities.dynamicvalue.common.SignInversionDynamicValue;
|
||||
|
|
@ -86,16 +84,12 @@ enum NecropolisFiendCostAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void prepareX(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
for (VariableCost variableCost : ability.getManaCostsToPay().getVariableCosts()) {
|
||||
if (variableCost instanceof VariableManaCost) {
|
||||
((VariableManaCost) variableCost).setMaxX(controller.getGraveyard().size());
|
||||
}
|
||||
}
|
||||
ability.setVariableCostsMinMax(0, controller.getGraveyard().size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ enum NemesisOfMortalsAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller != null) {
|
||||
CardUtil.reduceCost(ability, controller.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game));
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
*/
|
||||
public final class NightmarishEnd extends CardImpl {
|
||||
|
||||
private static final DynamicValue xValue = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
|
||||
private static final DynamicValue xValue = new SignInversionDynamicValue(CardsInControllerHandCount.ANY);
|
||||
|
||||
public NightmarishEnd(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ public final class NostalgicDreams extends CardImpl {
|
|||
public NostalgicDreams(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}{G}");
|
||||
|
||||
// As an additional cost to cast Nostalgic Dreams, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(new FilterCard("cards"), true));
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||
|
||||
// Return X target cards from your graveyard to your hand.
|
||||
Effect effect = new ReturnFromGraveyardToHandTargetEffect();
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
*/
|
||||
public final class OboroEnvoy extends CardImpl {
|
||||
|
||||
private static final DynamicValue xValue = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
|
||||
private static final DynamicValue xValue = new SignInversionDynamicValue(CardsInControllerHandCount.ANY);
|
||||
|
||||
public OboroEnvoy(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package mage.cards.o;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.InfoEffect;
|
||||
import mage.cards.*;
|
||||
|
|
@ -28,7 +27,7 @@ public final class OpenTheWay extends CardImpl {
|
|||
this.addAbility(new SimpleStaticAbility(
|
||||
Zone.ALL, new InfoEffect("X can't be greater than the number of players in the game")
|
||||
).setRuleAtTheTop(true));
|
||||
this.getSpellAbility().setCostAdjuster(OpenTheWayAdjuster.instance);
|
||||
this.getSpellAbility().setCostAdjuster(OpenTheWayCostAdjuster.instance);
|
||||
|
||||
// Reveal cards from the top of your library until you reveal X land cards. Put those land cards onto the battlefield tapped and the rest on the bottom of your library in a random order.
|
||||
this.getSpellAbility().addEffect(new OpenTheWayEffect());
|
||||
|
|
@ -44,14 +43,12 @@ public final class OpenTheWay extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum OpenTheWayAdjuster implements CostAdjuster {
|
||||
enum OpenTheWayCostAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
int playerCount = game.getPlayers().size();
|
||||
CardUtil.castStream(ability.getCosts().stream(), VariableManaCost.class)
|
||||
.forEach(cost -> cost.setMaxX(playerCount));
|
||||
public void prepareX(Ability ability, Game game) {
|
||||
ability.setVariableCostsMinMax(0, game.getState().getPlayersInRange(ability.getControllerId(), game, true).size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import mage.util.CardUtil;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Arketec
|
||||
*/
|
||||
public final class OsgirTheReconstructor extends CardImpl {
|
||||
|
|
@ -81,15 +80,15 @@ enum OsgirTheReconstructorCostAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void prepareCost(Ability ability, Game game) {
|
||||
int xValue = CardUtil.getSourceCostsTag(game, ability, "X", 0);
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
FilterCard filter = new FilterArtifactCard("an artifact card with mana value "+xValue+" from your graveyard");
|
||||
FilterCard filter = new FilterArtifactCard("an artifact card with mana value " + xValue + " from your graveyard");
|
||||
filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, xValue));
|
||||
for (Cost cost: ability.getCosts()) {
|
||||
for (Cost cost : ability.getCosts()) {
|
||||
if (cost instanceof ExileFromGraveCost) {
|
||||
cost.getTargets().set(0, new TargetCardInYourGraveyard(filter));
|
||||
}
|
||||
|
|
@ -104,7 +103,7 @@ class OsgirTheReconstructorCreateArtifactTokensEffect extends OneShotEffect {
|
|||
this.staticText = "Create two tokens that are copies of the exiled card.";
|
||||
}
|
||||
|
||||
private OsgirTheReconstructorCreateArtifactTokensEffect(final OsgirTheReconstructorCreateArtifactTokensEffect effect) {
|
||||
private OsgirTheReconstructorCreateArtifactTokensEffect(final OsgirTheReconstructorCreateArtifactTokensEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
|
@ -127,11 +126,11 @@ class OsgirTheReconstructorCreateArtifactTokensEffect extends OneShotEffect {
|
|||
effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId())));
|
||||
effect.apply(game, source);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OsgirTheReconstructorCreateArtifactTokensEffect copy() {
|
||||
public OsgirTheReconstructorCreateArtifactTokensEffect copy() {
|
||||
return new OsgirTheReconstructorCreateArtifactTokensEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import mage.cards.CardImpl;
|
|||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +31,7 @@ public final class OverbeingOfMyth extends CardImpl {
|
|||
this.toughness = new MageInt(0);
|
||||
|
||||
// Overbeing of Myth's power and toughness are each equal to the number of cards in your hand.
|
||||
DynamicValue number = CardsInControllerHandCount.instance;
|
||||
DynamicValue number = CardsInControllerHandCount.ANY;
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(number)));
|
||||
|
||||
// At the beginning of your draw step, draw an additional card.
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ enum PhyrexianPurgeCostAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void increaseCost(Ability ability, Game game) {
|
||||
int numTargets = ability.getTargets().get(0).getTargets().size();
|
||||
if (numTargets > 0) {
|
||||
ability.addCost(new PayLifeCost(numTargets * 3));
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ enum PlateArmorAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller != null) {
|
||||
int count = equipmentCount.calculate(game, ability, null);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public final class PresenceOfTheWise extends CardImpl {
|
|||
|
||||
// You gain 2 life for each card in your hand.
|
||||
this.getSpellAbility().addEffect(new GainLifeEffect(
|
||||
new MultipliedValue(CardsInControllerHandCount.instance, 2),"You gain 2 life for each card in your hand"));
|
||||
new MultipliedValue(CardsInControllerHandCount.ANY, 2),"You gain 2 life for each card in your hand"));
|
||||
}
|
||||
|
||||
private PresenceOfTheWise(final PresenceOfTheWise card) {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,8 @@ import mage.MageObject;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.CostAdjuster;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.costadjusters.ImprintedManaValueXCostAdjuster;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
|
|
@ -42,10 +39,10 @@ public final class PrototypePortal extends CardImpl {
|
|||
.setAbilityWord(AbilityWord.IMPRINT)
|
||||
);
|
||||
|
||||
// {X}, {tap}: Create a token that's a copy of the exiled card. X is the converted mana cost of that card.
|
||||
// {X}, {T}: Create a token that's a copy of the exiled card. X is the converted mana cost of that card.
|
||||
Ability ability = new SimpleActivatedAbility(new PrototypePortalCreateTokenEffect(), new ManaCostsImpl<>("{X}"));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.setCostAdjuster(PrototypePortalAdjuster.instance);
|
||||
ability.setCostAdjuster(ImprintedManaValueXCostAdjuster.instance);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
|
|
@ -59,31 +56,6 @@ public final class PrototypePortal extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum PrototypePortalAdjuster implements CostAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
Permanent card = game.getPermanent(ability.getSourceId());
|
||||
if (card != null) {
|
||||
if (!card.getImprinted().isEmpty()) {
|
||||
Card imprinted = game.getCard(card.getImprinted().get(0));
|
||||
if (imprinted != null) {
|
||||
ability.clearManaCostsToPay();
|
||||
ability.addManaCostsToPay(new GenericManaCost(imprinted.getManaValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no {X} anymore as we already have imprinted the card with defined manacost
|
||||
for (ManaCost cost : ability.getManaCostsToPay()) {
|
||||
if (cost instanceof VariableCost) {
|
||||
cost.setPaid();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PrototypePortalEffect extends OneShotEffect {
|
||||
|
||||
PrototypePortalEffect() {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public final class PsychosisCrawler extends CardImpl {
|
|||
this.power = new MageInt(0);
|
||||
this.toughness = new MageInt(0);
|
||||
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerToughnessSourceEffect(CardsInControllerHandCount.ANY)));
|
||||
this.addAbility(new DrawCardControllerTriggeredAbility(new LoseLifeOpponentsEffect(1), false));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ enum PteramanderAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
int count = cardsCount.calculate(game, ability, null);
|
||||
CardUtil.reduceCost(ability, count);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ enum QuestForTheNecropolisAdjuster implements CostAdjuster {
|
|||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
int amount = Optional
|
||||
.ofNullable(ability.getSourcePermanentIfItStillExists(game))
|
||||
.map(permanent -> permanent.getCounters(game).getCount(CounterType.QUEST))
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public final class RalsStaticaster extends CardImpl {
|
|||
// Whenever Ral's Staticaster attacks, if you control a Ral planeswalker, Ral's Staticaster gets +1/+0 for each card in your hand until end of turn.
|
||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||
new AttacksTriggeredAbility(new BoostSourceEffect(
|
||||
CardsInControllerHandCount.instance, StaticValue.get(0),
|
||||
CardsInControllerHandCount.ANY, StaticValue.get(0),
|
||||
Duration.EndOfTurn), false),
|
||||
new PermanentsOnTheBattlefieldCondition(filter),
|
||||
"Whenever {this} attacks, if you control a Ral planeswalker, "
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ enum RazorlashTransmograntAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
if (makeMap(game, ability).values().stream().anyMatch(x -> x >= 4)) {
|
||||
CardUtil.reduceCost(ability, 4);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public final class RestlessDreams extends CardImpl {
|
|||
public RestlessDreams(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}");
|
||||
|
||||
// As an additional cost to cast Restless Dreams, discard X cards.
|
||||
// As an additional cost to cast this spell, discard X cards.
|
||||
this.getSpellAbility().addCost(new DiscardXTargetCost(StaticFilters.FILTER_CARD_CARDS, true));
|
||||
|
||||
// Return X target creature cards from your graveyard to your hand.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public final class RobobrainWarMind extends CardImpl {
|
|||
this.toughness = new MageInt(5);
|
||||
|
||||
// Robobrain War Mind's power is equal to the number of cards in your hand.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerSourceEffect(CardsInControllerHandCount.instance)));
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetBasePowerSourceEffect(CardsInControllerHandCount.ANY)));
|
||||
|
||||
// When Robobrain War Mind enters the battlefield, you get an amount of {E} equal to the number of artifact creatures you control.
|
||||
this.addAbility(new EntersBattlefieldTriggeredAbility(new GetEnergyCountersControllerEffect(new PermanentsOnBattlefieldCount(filter))
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public final class SageOfAncientLore extends CardImpl {
|
|||
this.secondSideCardClazz = mage.cards.w.WerewolfOfAncientHunger.class;
|
||||
|
||||
// Sage of Ancient Lore's power and toughness are each equal to the number of cards in your hand.
|
||||
DynamicValue xValue = CardsInControllerHandCount.instance;
|
||||
DynamicValue xValue = CardsInControllerHandCount.ANY;
|
||||
this.addAbility(new SimpleStaticAbility(Zone.ALL,
|
||||
new ConditionalContinuousEffect(new SetBasePowerToughnessSourceEffect(xValue),
|
||||
new TransformedCondition(true), "{this}'s power and toughness are each equal to the total number of cards in your hand")));
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ enum SanctumOfTranquilLightAdjuster implements CostAdjuster {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void adjustCosts(Ability ability, Game game) {
|
||||
public void reduceCost(Ability ability, Game game) {
|
||||
Player controller = game.getPlayer(ability.getControllerId());
|
||||
if (controller != null) {
|
||||
CardUtil.reduceCost(ability, count.calculate(game, ability, null));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue