Merge pull request #13516 from magefree/cost-adjusters-rework

This commit is contained in:
Oleg Agafonov 2025-04-08 22:30:45 +03:00 committed by GitHub
commit 2a1eebc5fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
168 changed files with 1635 additions and 540 deletions

View file

@ -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;

View file

@ -1709,6 +1709,8 @@ public class HumanPlayer extends PlayerImpl {
if (response.getInteger() != null) {
break;
}
// TODO: add response verify here
}
if (response.getInteger() != null) {

View file

@ -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

View file

@ -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) {
@ -49,15 +36,3 @@ public final class AbandonHope extends CardImpl {
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)));
}
}
}

View file

@ -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));

View file

@ -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)));
}
}
}

View file

@ -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()));
}
}

View file

@ -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

View file

@ -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);

View file

@ -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()));
}

View file

@ -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);

View file

@ -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);

View file

@ -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));
}
}

View file

@ -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);

View file

@ -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));
}

View file

@ -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);
}
}

View file

@ -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);

View file

@ -33,7 +33,7 @@ public final class BodyOfKnowledge extends CardImpl {
this.addAbility(new SimpleStaticAbility(
Zone.ALL,
new SetBasePowerToughnessSourceEffect(
CardsInControllerHandCount.instance
CardsInControllerHandCount.ANY
)
));

View file

@ -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);
}

View file

@ -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}");

View file

@ -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);

View file

@ -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());

View file

@ -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);
}

View file

@ -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) {

View file

@ -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));
}
}

View file

@ -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}");

View file

@ -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}")));

View file

@ -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")));

View file

@ -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);

View file

@ -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));

View file

@ -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")));

View file

@ -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");

View file

@ -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)));
}

View file

@ -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));

View file

@ -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());

View file

@ -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);
}

View file

@ -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));
}
}

View file

@ -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());

View file

@ -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);
}
}
}

View file

@ -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());
}

View file

@ -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());

View file

@ -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));
}
}

View file

@ -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));

View file

@ -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"));
}

View file

@ -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;

View file

@ -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));

View file

@ -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));

View file

@ -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);

View file

@ -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
));

View file

@ -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);

View file

@ -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() ?

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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.

View file

@ -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);

View file

@ -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}")));

View file

@ -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);

View file

@ -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.

View file

@ -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));

View file

@ -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);

View file

@ -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}")));
}

View file

@ -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);

View file

@ -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());
}
}
}

View file

@ -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."

View file

@ -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());

View file

@ -74,7 +74,7 @@ class HighestLifeTotalAmongOpponentsCount implements DynamicValue {
@Override
public DynamicValue copy() {
return CardsInControllerHandCount.instance;
return CardsInControllerHandCount.ANY;
}
@Override

View file

@ -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"
)));
}

View file

@ -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));
}
}

View file

@ -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) {

View file

@ -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());

View file

@ -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));

View file

@ -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) {

View file

@ -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.

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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());
}
}

View file

@ -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));

View file

@ -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}");

View file

@ -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();

View file

@ -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}");

View file

@ -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());
}
}

View file

@ -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);
}
}

View file

@ -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.

View file

@ -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));

View file

@ -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);

View file

@ -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) {

View file

@ -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() {

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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))

View file

@ -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, "

View file

@ -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);
}

View file

@ -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.

View file

@ -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))

View file

@ -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")));

View file

@ -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