finished refactoring cost adjuster methods

This commit is contained in:
Evan Kranzler 2021-03-23 20:23:58 -04:00
parent 238509552c
commit bfd1a76bda
8 changed files with 224 additions and 240 deletions

View file

@ -2,16 +2,14 @@ package mage.cards.g;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.CostAdjuster;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
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.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
@ -29,35 +27,15 @@ public final class GhostfireBlade extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+2
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)));
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(2, 2)));
// Equip {3}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(3))); // todo
Ability ability = new EquipAbility(3);
ability.setCostAdjuster(GhostfireBladeAdjuster.instance);
this.addAbility(ability);
// Ghostfire Blade's equip ability costs {2} less to activate if it targets a colorless creature.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("{this}'s equip ability costs {2} less to activate if it targets a colorless creature")));
}
@Override
public void adjustCosts(Ability ability, Game game) {
if (ability instanceof EquipAbility) {
if (game.inCheckPlayableState()) {
// checking state
boolean canSelectColorlessCreature = CardUtil.getAllPossibleTargets(ability, game).stream()
.map(game::getPermanent)
.filter(Objects::nonNull)
.anyMatch(permanent -> permanent.getColor(game).isColorless());
if (canSelectColorlessCreature) {
CardUtil.reduceCost(ability, 2);
}
} else {
// real cast state
Permanent targetCreature = game.getPermanent(ability.getTargets().getFirstTarget());
if (targetCreature != null && targetCreature.getColor(game).isColorless()) {
CardUtil.reduceCost(ability, 2);
}
}
}
this.addAbility(new SimpleStaticAbility(new InfoEffect("{this}'s equip ability costs {2} less to activate if it targets a colorless creature")));
}
private GhostfireBlade(final GhostfireBlade card) {
@ -69,3 +47,28 @@ public final class GhostfireBlade extends CardImpl {
return new GhostfireBlade(this);
}
}
enum GhostfireBladeAdjuster implements CostAdjuster {
instance;
@Override
public void adjustCosts(Ability ability, Game game) {
// checking state
if (game.inCheckPlayableState()) {
if (CardUtil
.getAllPossibleTargets(ability, game)
.stream()
.map(game::getPermanent)
.filter(Objects::nonNull)
.noneMatch(permanent -> permanent.getColor(game).isColorless())) {
return;
}
} else {
Permanent permanent = game.getPermanent(ability.getFirstTarget());
if (permanent == null || !permanent.getColor(game).isColorless()) {
return;
}
}
CardUtil.reduceCost(ability, 2);
}
}

View file

@ -1,10 +1,9 @@
package mage.cards.k;
import java.util.UUID;
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.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
@ -17,11 +16,12 @@ import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
*
* @author anonymous
*/
public final class KnollspineInvocation extends CardImpl {
@ -29,32 +29,16 @@ public final class KnollspineInvocation extends CardImpl {
private static final FilterCard filter = new FilterCard("a card with converted mana cost X");
public KnollspineInvocation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}{R}");
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.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance, true), new ManaCostsImpl<>("{X}"));
ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter)));
ability.addTarget(new TargetAnyTarget());
ability.setCostAdjuster(KnollspineInvocationAdjuster.instance);
this.addAbility(ability);
}
@Override
public void adjustCosts(Ability ability, Game game) {
if (ability instanceof SimpleActivatedAbility) {
int xValue = ability.getManaCostsToPay().getX();
for (Cost cost : ability.getCosts()) {
if (cost instanceof DiscardTargetCost) {
DiscardTargetCost discardCost = (DiscardTargetCost) cost;
discardCost.getTargets().clear();
FilterCard adjustedFilter = filter.copy(); // don't use it directly, it's static!!!!
adjustedFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
discardCost.addTarget(new TargetCardInHand(adjustedFilter));
return;
}
}
}
}
private KnollspineInvocation(final KnollspineInvocation card) {
super(card);
}
@ -64,3 +48,23 @@ public final class KnollspineInvocation extends CardImpl {
return new KnollspineInvocation(this);
}
}
enum KnollspineInvocationAdjuster implements CostAdjuster {
instance;
@Override
public void adjustCosts(Ability ability, Game game) {
int xValue = ability.getManaCostsToPay().getX();
for (Cost cost : ability.getCosts()) {
if (!(cost instanceof DiscardTargetCost)) {
continue;
}
DiscardTargetCost discardCost = (DiscardTargetCost) cost;
discardCost.getTargets().clear();
FilterCard adjustedFilter = new FilterCard("a card with converted mana cost X");
adjustedFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, xValue));
discardCost.addTarget(new TargetCardInHand(adjustedFilter));
return;
}
}
}

View file

@ -3,6 +3,7 @@ package mage.cards.l;
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.InfoEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
@ -11,15 +12,17 @@ import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.Objects;
import java.util.UUID;
/**
*
* @author Styxo
*/
public final class Lightsaber extends CardImpl {
@ -29,25 +32,18 @@ public final class Lightsaber extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equiped creature gets +1/+0 and has firsttrike
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 0)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT)));
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 0)));
this.addAbility(new SimpleStaticAbility(new GainAbilityAttachedEffect(
FirstStrikeAbility.getInstance(), AttachmentType.EQUIPMENT
).setText("and has first strike")));
// Equip 3
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(3)));
Ability ability = new EquipAbility(3);
ability.setCostAdjuster(LightsaberAdjuster.instance);
this.addAbility(ability);
// Lightsaber's equip ability costs {1} if it targets a Jedi or Sith.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect("{this}'s equip ability costs {1} if it targets a Jedi or Sith")));
}
@Override
public void adjustCosts(Ability ability, Game game) {
if (ability instanceof EquipAbility) {
Permanent targetCreature = game.getPermanent(ability.getTargets().getFirstTarget());
if (targetCreature != null && (targetCreature.hasSubtype(SubType.SITH, game) || targetCreature.hasSubtype(SubType.JEDI, game))) {
CardUtil.increaseCost(ability, 1 - ability.getManaCostsToPay().convertedManaCost());
}
}
this.addAbility(new SimpleStaticAbility(new InfoEffect("{this}'s equip ability costs {1} if it targets a Jedi or Sith")));
}
private Lightsaber(final Lightsaber card) {
@ -59,3 +55,30 @@ public final class Lightsaber extends CardImpl {
return new Lightsaber(this);
}
}
enum LightsaberAdjuster implements CostAdjuster {
instance;
@Override
public void adjustCosts(Ability ability, Game game) {
if (game.inCheckPlayableState()) {
if (CardUtil
.getAllPossibleTargets(ability, game)
.stream()
.map(game::getPermanent)
.filter(Objects::nonNull)
.noneMatch(permanent -> permanent.hasSubtype(SubType.SITH, game)
|| permanent.hasSubtype(SubType.JEDI, game))) {
return;
}
} else {
Permanent permanent = game.getPermanent(ability.getFirstTarget());
if (permanent == null || !(permanent.hasSubtype(SubType.SITH, game)
|| permanent.hasSubtype(SubType.JEDI, game))) {
return;
}
}
ability.getCosts().clear();
ability.addCost(new GenericManaCost(1));
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
@ -22,10 +21,9 @@ import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -35,8 +33,9 @@ import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class MarathWillOfTheWild extends CardImpl {
@ -58,7 +57,7 @@ public final class MarathWillOfTheWild extends CardImpl {
// {X}, Remove X +1/+1 counters from Marath: Choose one - Put X +1/+1 counters on target creature;
effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), ManacostVariableValue.instance);
effect.setText("Put X +1/+1 counters on target creature");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
Ability ability = new SimpleActivatedAbility(effect, new ManaCostsImpl("{X}"));
ability.addCost(new MarathWillOfTheWildRemoveCountersCost());
ability.addTarget(new TargetCreaturePermanent());
@ -83,24 +82,6 @@ public final class MarathWillOfTheWild extends CardImpl {
this.addAbility(ability);
}
@Override
public void adjustCosts(Ability ability, Game game) {
if (ability instanceof SimpleActivatedAbility && ability.getModes().size() == 3) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null) {
int amount = sourcePermanent.getCounters(game).getCount(CounterType.P1P1);
if (amount > 0) {
for (VariableCost cost : ability.getManaCostsToPay().getVariableCosts()) {
if (cost instanceof VariableManaCost) {
((VariableManaCost) cost).setMaxX(amount);
break;
}
}
}
}
}
}
private MarathWillOfTheWild(final MarathWillOfTheWild card) {
super(card);
}
@ -113,12 +94,12 @@ public final class MarathWillOfTheWild extends CardImpl {
class MarathWillOfTheWildCreateTokenEffect extends OneShotEffect {
public MarathWillOfTheWildCreateTokenEffect() {
MarathWillOfTheWildCreateTokenEffect() {
super(Outcome.PutCreatureInPlay);
staticText = "create an X/X green Elemental creature token";
}
public MarathWillOfTheWildCreateTokenEffect(final MarathWillOfTheWildCreateTokenEffect effect) {
private MarathWillOfTheWildCreateTokenEffect(final MarathWillOfTheWildCreateTokenEffect effect) {
super(effect);
}
@ -144,12 +125,12 @@ class MarathWillOfTheWildCreateTokenEffect extends OneShotEffect {
class MarathWillOfTheWildRemoveCountersCost extends CostImpl {
public MarathWillOfTheWildRemoveCountersCost() {
MarathWillOfTheWildRemoveCountersCost() {
this.text = "Remove X +1/+1 counters from Marath";
}
public MarathWillOfTheWildRemoveCountersCost(MarathWillOfTheWildRemoveCountersCost cost) {
private MarathWillOfTheWildRemoveCountersCost(MarathWillOfTheWildRemoveCountersCost cost) {
super(cost);
}

View file

@ -4,6 +4,7 @@ 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;
@ -35,11 +36,14 @@ public final class PrototypePortal extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// Imprint - When Prototype Portal enters the battlefield, you may exile an artifact card from your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new PrototypePortalEffect(), true));
this.addAbility(new EntersBattlefieldTriggeredAbility(
new PrototypePortalEffect(), true, "<i>Imprint</i> &mdash; "
));
// {X}, {tap}: Create a token that's a copy of the exiled card. X is the converted mana cost of that card.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PrototypePortalCreateTokenEffect(), new ManaCostsImpl("{X}"));
Ability ability = new SimpleActivatedAbility(new PrototypePortalCreateTokenEffect(), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
ability.setCostAdjuster(PrototypePortalAdjuster.instance);
this.addAbility(ability);
}
@ -47,6 +51,15 @@ public final class PrototypePortal extends CardImpl {
super(card);
}
@Override
public PrototypePortal copy() {
return new PrototypePortal(this);
}
}
enum PrototypePortalAdjuster implements CostAdjuster {
instance;
@Override
public void adjustCosts(Ability ability, Game game) {
Permanent card = game.getPermanent(ability.getSourceId());
@ -66,21 +79,16 @@ public final class PrototypePortal extends CardImpl {
}
}
}
@Override
public PrototypePortal copy() {
return new PrototypePortal(this);
}
}
class PrototypePortalEffect extends OneShotEffect {
public PrototypePortalEffect() {
PrototypePortalEffect() {
super(Outcome.Benefit);
staticText = "exile an artifact card from your hand";
}
public PrototypePortalEffect(PrototypePortalEffect effect) {
private PrototypePortalEffect(PrototypePortalEffect effect) {
super(effect);
}
@ -115,12 +123,12 @@ class PrototypePortalEffect extends OneShotEffect {
class PrototypePortalCreateTokenEffect extends OneShotEffect {
public PrototypePortalCreateTokenEffect() {
PrototypePortalCreateTokenEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Create a token that's a copy of the exiled card. X is the converted mana cost of that card";
}
public PrototypePortalCreateTokenEffect(final PrototypePortalCreateTokenEffect effect) {
private PrototypePortalCreateTokenEffect(final PrototypePortalCreateTokenEffect effect) {
super(effect);
}

View file

@ -1,114 +1,70 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.CostAdjuster;
import mage.abilities.costs.common.ExileFromGraveCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class SkeletalScrying extends CardImpl {
public SkeletalScrying(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{B}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{B}");
// As an additional cost to cast Skeletal Scrying, exile X cards from your graveyard.
Ability ability = new SimpleStaticAbility(Zone.ALL, new SkeletalScryingRuleEffect());
Ability ability = new SimpleStaticAbility(
Zone.ALL,
new InfoEffect(
"as an additional cost to cast this spell, " +
"exile X cards from your graveyard"
));
ability.setRuleAtTheTop(true);
this.addAbility(ability);
// You draw X cards and you lose X life.
this.getSpellAbility().addEffect(new SkeletalScryingEffect(ManacostVariableValue.instance));
this.getSpellAbility().setCostAdjuster(SkeletalScryingAdjuster.instance);
// You draw X cards and you lose X life.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(
ManacostVariableValue.instance
).setText("you draw X cards"));
this.getSpellAbility().addEffect(new GainLifeEffect(
ManacostVariableValue.instance
).concatBy("and"));
}
private SkeletalScrying(final SkeletalScrying card) {
super(card);
}
@Override
public void adjustCosts(Ability ability, Game game) {
int xValue = ability.getManaCostsToPay().getX();
if (xValue > 0) {
ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(xValue, xValue, new FilterCard("cards from your graveyard"))));
}
}
@Override
public SkeletalScrying copy() {
return new SkeletalScrying(this);
}
}
class SkeletalScryingRuleEffect extends OneShotEffect {
public SkeletalScryingRuleEffect() {
super(Outcome.Benefit);
this.staticText = "as an additional cost to cast this spell, exile X cards from your graveyard";
}
public SkeletalScryingRuleEffect(final SkeletalScryingRuleEffect effect) {
super(effect);
}
enum SkeletalScryingAdjuster implements CostAdjuster {
instance;
private static final FilterCard filter = new FilterCard("cards from your graveyard");
@Override
public SkeletalScryingRuleEffect copy() {
return new SkeletalScryingRuleEffect(this);
public void adjustCosts(Ability ability, Game game) {
int xValue = ability.getManaCostsToPay().getX();
if (xValue > 0) {
ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(xValue, xValue, filter)));
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
}
class SkeletalScryingEffect extends OneShotEffect {
protected DynamicValue amount;
public SkeletalScryingEffect(int amount) {
this(StaticValue.get(amount));
}
public SkeletalScryingEffect(DynamicValue amount) {
super(Outcome.Neutral);
this.amount = amount.copy();
staticText = "You draw " + amount + " cards and you lose " + amount + " life";
}
public SkeletalScryingEffect(final SkeletalScryingEffect effect) {
super(effect);
this.amount = effect.amount;
}
@Override
public SkeletalScryingEffect copy() {
return new SkeletalScryingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if ( controller != null ) {
controller.drawCards(amount.calculate(game, source, this), source, game);
controller.loseLife(amount.calculate(game, source, this), game, source, false);
return true;
}
return false;
}
}

View file

@ -1,10 +1,9 @@
package mage.cards.s;
import java.util.UUID;
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;
@ -26,8 +25,9 @@ import mage.target.TargetCard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class SoulFoundry extends CardImpl {
@ -36,22 +36,32 @@ public final class SoulFoundry extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// Imprint - When Soul Foundry enters the battlefield, you may exile a creature card from your hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SoulFoundryImprintEffect(), true, "<i>Imprint</i> &mdash; "));
this.addAbility(new EntersBattlefieldTriggeredAbility(
new SoulFoundryImprintEffect(), true, "<i>Imprint</i> &mdash; "
));
// {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(Zone.BATTLEFIELD, new SoulFoundryEffect(), new ManaCostsImpl("{X}"));
Ability ability = new SimpleActivatedAbility(new SoulFoundryEffect(), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
ability.setCostAdjuster(SoulFoundryAdjuster.instance);
this.addAbility(ability);
}
private SoulFoundry(final SoulFoundry card) {
super(card);
}
@Override
public SoulFoundry copy() {
return new SoulFoundry(this);
}
}
enum SoulFoundryAdjuster implements CostAdjuster {
instance;
@Override
public void adjustCosts(Ability ability, Game game) {
if (ability instanceof SimpleActivatedAbility) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null) {
if (!sourcePermanent.getImprinted().isEmpty()) {
@ -70,12 +80,6 @@ public final class SoulFoundry extends CardImpl {
}
}
}
}
@Override
public SoulFoundry copy() {
return new SoulFoundry(this);
}
}
class SoulFoundryImprintEffect extends OneShotEffect {
@ -86,12 +90,12 @@ class SoulFoundryImprintEffect extends OneShotEffect {
filter.add(CardType.CREATURE.getPredicate());
}
public SoulFoundryImprintEffect() {
SoulFoundryImprintEffect() {
super(Outcome.Neutral);
staticText = "you may exile a creature card from your hand";
}
public SoulFoundryImprintEffect(SoulFoundryImprintEffect effect) {
private SoulFoundryImprintEffect(SoulFoundryImprintEffect effect) {
super(effect);
}
@ -128,12 +132,12 @@ class SoulFoundryImprintEffect extends OneShotEffect {
class SoulFoundryEffect extends OneShotEffect {
public SoulFoundryEffect() {
SoulFoundryEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Create a token that's a copy of the exiled card. X is the converted mana cost of that card";
}
public SoulFoundryEffect(final SoulFoundryEffect effect) {
private SoulFoundryEffect(final SoulFoundryEffect effect) {
super(effect);
}

View file

@ -1,18 +1,16 @@
package mage.cards.v;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.InvertCondition;
import mage.abilities.condition.common.SourceTappedCondition;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.CostAdjuster;
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.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.dynamicvalue.common.CountersSourceCount;
import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.effects.common.DamageTargetEffect;
@ -22,51 +20,44 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetAnyTarget;
import java.util.UUID;
/**
*
* @author L_J
*/
public final class VoodooDoll extends CardImpl {
public VoodooDoll(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
// At the beginning of your upkeep, put a pin counter on Voodoo Doll.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.PIN.createInstance()), TargetController.YOU, false));
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new AddCountersSourceEffect(CounterType.PIN.createInstance()), TargetController.YOU, false
));
// At the beginning of your end step, if Voodoo Doll is untapped, destroy Voodoo Doll and it deals damage to you equal to the number of pin counters on it.
Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new DestroySourceEffect(), TargetController.YOU,
new InvertCondition(SourceTappedCondition.instance), false);
Ability ability = new ConditionalInterveningIfTriggeredAbility(
new BeginningOfEndStepTriggeredAbility(
new DestroySourceEffect(), TargetController.YOU, false
), new InvertCondition(SourceTappedCondition.instance), "At the beginning of your end step, " +
"if {this} is untapped, destroy {this} and it deals damage to you equal to the number of pin counters on it."
);
ability.addEffect(new DamageControllerEffect(new CountersSourceCount(CounterType.PIN)));
this.addAbility(ability);
// {X}{X}, {T}: Voodoo Doll deals damage equal to the number of pin counters on it to any target. X is the number of pin counters on Voodoo Doll.
Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new CountersSourceCount(CounterType.PIN)), new ManaCostsImpl("{X}{X}"));
ability2.addCost(new TapSourceCost());
ability2.addTarget(new TargetAnyTarget());
for (VariableCost cost : ability2.getManaCosts().getVariableCosts()) {
if (cost instanceof VariableManaCost) {
((VariableManaCost) cost).setMaxX(0);
break;
}
}
this.addAbility(ability2);
}
@Override
public void adjustCosts(Ability ability, Game game) {
if (ability instanceof SimpleActivatedAbility) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null) {
int pin = sourcePermanent.getCounters(game).getCount(CounterType.PIN);
ability.getManaCostsToPay().clear();
ability.getManaCostsToPay().add(0, new GenericManaCost(pin * 2));
}
}
// {X}{X}, {T}: Voodoo Doll deals damage equal to the number of pin counters on it to any target. X is the number of pin counters on Voodoo Doll.
ability = new SimpleActivatedAbility(
new DamageTargetEffect(new CountersSourceCount(CounterType.PIN)), new ManaCostsImpl("{X}{X}")
);
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
ability.setCostAdjuster(VoodooDollAdjuster.instance);
this.addAbility(ability);
}
private VoodooDoll(final VoodooDoll card) {
@ -78,3 +69,17 @@ public final class VoodooDoll extends CardImpl {
return new VoodooDoll(this);
}
}
enum VoodooDollAdjuster implements CostAdjuster {
instance;
@Override
public void adjustCosts(Ability ability, Game game) {
Permanent sourcePermanent = game.getPermanent(ability.getSourceId());
if (sourcePermanent != null) {
int pin = sourcePermanent.getCounters(game).getCount(CounterType.PIN);
ability.getManaCostsToPay().clear();
ability.getManaCostsToPay().add(0, new GenericManaCost(pin * 2));
}
}
}