From 8d89c99f1763cb5d2f728c007bc52e0e4189ee9b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 10 Sep 2020 10:50:56 -0400 Subject: [PATCH] refactored cards which remove all counters to use a single class --- Mage.Sets/src/mage/cards/e/EssenceBottle.java | 70 +++-------- Mage.Sets/src/mage/cards/j/JarOfEyeballs.java | 109 +++--------------- Mage.Sets/src/mage/cards/m/MoltenHydra.java | 100 ++++------------ Mage.Sets/src/mage/cards/s/SageOfHours.java | 63 ++-------- .../src/mage/cards/t/TortureChamber.java | 66 +++-------- .../src/mage/cards/v/VishKalBloodArbiter.java | 99 ++++------------ .../common/RemoveAllCountersSourceCost.java | 57 +++++++++ 7 files changed, 151 insertions(+), 413 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/costs/common/RemoveAllCountersSourceCost.java diff --git a/Mage.Sets/src/mage/cards/e/EssenceBottle.java b/Mage.Sets/src/mage/cards/e/EssenceBottle.java index acd745a8da2..2622cf8f13c 100644 --- a/Mage.Sets/src/mage/cards/e/EssenceBottle.java +++ b/Mage.Sets/src/mage/cards/e/EssenceBottle.java @@ -1,11 +1,9 @@ - package mage.cards.e; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.RemoveAllCountersSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; @@ -14,29 +12,30 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; +import java.util.UUID; + /** - * * @author North */ public final class EssenceBottle extends CardImpl { public EssenceBottle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + // {3}, {tap}: Put an elixir counter on Essence Bottle. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new AddCountersSourceEffect(CounterType.ELIXIR.createInstance()), - new GenericManaCost(3)); + SimpleActivatedAbility ability = new SimpleActivatedAbility( + new AddCountersSourceEffect(CounterType.ELIXIR.createInstance()), new GenericManaCost(3) + ); ability.addCost(new TapSourceCost()); this.addAbility(ability); + // {tap}, Remove all elixir counters from Essence Bottle: You gain 2 life for each elixir counter removed this way. - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EssenceBottleEffect(), new TapSourceCost()); - ability.addCost(new EssenceBottleCost()); + ability = new SimpleActivatedAbility(new EssenceBottleEffect(), new TapSourceCost()); + ability.addCost(new RemoveAllCountersSourceCost(CounterType.ELIXIR)); this.addAbility(ability); } @@ -50,49 +49,6 @@ public final class EssenceBottle extends CardImpl { } } -class EssenceBottleCost extends CostImpl { - - private int removedCounters; - - public EssenceBottleCost() { - super(); - this.removedCounters = 0; - this.text = "Remove all elixir counters from {this}"; - } - - public EssenceBottleCost(EssenceBottleCost cost) { - super(cost); - this.removedCounters = cost.removedCounters; - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(ability.getSourceId()); - if (permanent != null) { - this.removedCounters = permanent.getCounters(game).getCount(CounterType.ELIXIR); - if (this.removedCounters > 0) { - permanent.removeCounters(CounterType.ELIXIR.createInstance(this.removedCounters), game); - } - } - this.paid = true; - return true; - } - - @Override - public EssenceBottleCost copy() { - return new EssenceBottleCost(this); - } - - public int getRemovedCounters() { - return this.removedCounters; - } -} - class EssenceBottleEffect extends OneShotEffect { public EssenceBottleEffect() { @@ -113,8 +69,8 @@ class EssenceBottleEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { int countersRemoved = 0; for (Cost cost : source.getCosts()) { - if (cost instanceof EssenceBottleCost) { - countersRemoved = ((EssenceBottleCost) cost).getRemovedCounters(); + if (cost instanceof RemoveAllCountersSourceCost) { + countersRemoved = ((RemoveAllCountersSourceCost) cost).getRemovedCounters(); } } Player player = game.getPlayer(source.getControllerId()); diff --git a/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java b/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java index 5ea98a196fc..e14b588813b 100644 --- a/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java +++ b/Mage.Sets/src/mage/cards/j/JarOfEyeballs.java @@ -1,12 +1,10 @@ - package mage.cards.j; -import java.util.UUID; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.RemoveAllCountersSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; @@ -20,16 +18,14 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; +import java.util.UUID; + /** - * * @author North */ public final class JarOfEyeballs extends CardImpl { @@ -38,13 +34,17 @@ public final class JarOfEyeballs extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // Whenever a creature you control dies, put two eyeball counters on Jar of Eyeballs. - this.addAbility(new JarOfEyeballsTriggeredAbility()); + this.addAbility(new DiesCreatureTriggeredAbility( + new AddCountersSourceEffect(CounterType.EYEBALL.createInstance(2)), + false, StaticFilters.FILTER_CONTROLLED_A_CREATURE + )); + // {3}, {tap}, Remove all eyeball counters from Jar of Eyeballs: // Look at the top X cards of your library, where X is the number of eyeball counters removed this way. // Put one of them into your hand and the rest on the bottom of your library in any order. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JarOfEyeballsEffect(), new GenericManaCost(3)); + SimpleActivatedAbility ability = new SimpleActivatedAbility(new JarOfEyeballsEffect(), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); - ability.addCost(new JarOfEyeballsCost()); + ability.addCost(new RemoveAllCountersSourceCost(CounterType.EYEBALL)); this.addAbility(ability); } @@ -58,87 +58,6 @@ public final class JarOfEyeballs extends CardImpl { } } -class JarOfEyeballsTriggeredAbility extends TriggeredAbilityImpl { - - public JarOfEyeballsTriggeredAbility() { - super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.EYEBALL.createInstance(2))); - } - - public JarOfEyeballsTriggeredAbility(final JarOfEyeballsTriggeredAbility ability) { - super(ability); - } - - @Override - public JarOfEyeballsTriggeredAbility copy() { - return new JarOfEyeballsTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD - && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) { - Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent.isControlledBy(this.getControllerId()) && permanent.isCreature()) { - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever a creature you control dies, " + super.getRule(); - } -} - -class JarOfEyeballsCost extends CostImpl { - - private int removedCounters; - - public JarOfEyeballsCost() { - super(); - this.removedCounters = 0; - this.text = "Remove all eyeball counters from {this}"; - } - - public JarOfEyeballsCost(JarOfEyeballsCost cost) { - super(cost); - this.removedCounters = cost.removedCounters; - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(ability.getSourceId()); - if (permanent != null) { - this.removedCounters = permanent.getCounters(game).getCount(CounterType.EYEBALL); - if (this.removedCounters > 0) { - permanent.removeCounters(CounterType.EYEBALL.createInstance(this.removedCounters), game); - } - } - this.paid = true; - return true; - } - - @Override - public JarOfEyeballsCost copy() { - return new JarOfEyeballsCost(this); - } - - public int getRemovedCounters() { - return this.removedCounters; - } -} - class JarOfEyeballsEffect extends OneShotEffect { public JarOfEyeballsEffect() { @@ -163,8 +82,8 @@ class JarOfEyeballsEffect extends OneShotEffect { } int countersRemoved = 0; for (Cost cost : source.getCosts()) { - if (cost instanceof JarOfEyeballsCost) { - countersRemoved = ((JarOfEyeballsCost) cost).getRemovedCounters(); + if (cost instanceof RemoveAllCountersSourceCost) { + countersRemoved = ((RemoveAllCountersSourceCost) cost).getRemovedCounters(); } } Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, countersRemoved)); diff --git a/Mage.Sets/src/mage/cards/m/MoltenHydra.java b/Mage.Sets/src/mage/cards/m/MoltenHydra.java index 390d591d6c5..f78ba40dc35 100644 --- a/Mage.Sets/src/mage/cards/m/MoltenHydra.java +++ b/Mage.Sets/src/mage/cards/m/MoltenHydra.java @@ -1,12 +1,10 @@ - package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.RemoveAllCountersSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.DynamicValue; @@ -17,36 +15,37 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.counters.Counter; import mage.counters.CounterType; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetAnyTarget; +import java.util.UUID; + /** - * * @author Plopman */ public final class MoltenHydra extends CardImpl { - - public MoltenHydra(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HYDRA); this.power = new MageInt(1); this.toughness = new MageInt(1); // {1}{R}{R}: Put a +1/+1 counter on Molten Hydra. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), new ManaCostsImpl("{1}{R}{R}"))); + this.addAbility(new SimpleActivatedAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), new ManaCostsImpl<>("{1}{R}{R}") + )); + // {tap}, Remove all +1/+1 counters from Molten Hydra: Molten Hydra deals damage to any target equal to the number of +1/+1 counters removed this way. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new MotltenHydraDynamicValue()), new TapSourceCost()); - ability.addCost(new RemoveAllCountersSourceCost(CounterType.P1P1.createInstance())); + Ability ability = new SimpleActivatedAbility( + new DamageTargetEffect(MoltenHydraDynamicValue.instance), new TapSourceCost() + ); + ability.addCost(new RemoveAllCountersSourceCost(CounterType.P1P1)); ability.addTarget(new TargetAnyTarget()); this.addAbility(ability); - + } public MoltenHydra(final MoltenHydra card) { @@ -59,81 +58,23 @@ public final class MoltenHydra extends CardImpl { } } - - -class RemoveAllCountersSourceCost extends CostImpl { - - private int amount; - private String name; - - public RemoveAllCountersSourceCost(Counter counter) { - this.name = counter.getName(); - this.amount = counter.getCount(); - this.text = "Remove all " + name + " counters from {this}"; - } - - public RemoveAllCountersSourceCost(RemoveAllCountersSourceCost cost) { - super(cost); - this.amount = cost.amount; - this.name = cost.name; - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null) { - this.amount = permanent.getCounters(game).getCount(name); - permanent.removeCounters(name, amount, game); - this.paid = true; - } - else - { - this.amount = 0; - } - return paid; - } - - @Override - public RemoveAllCountersSourceCost copy() { - return new RemoveAllCountersSourceCost(this); - } - - public int getAmount() { - return amount; - } - - -} - -class MotltenHydraDynamicValue implements DynamicValue { - - - public MotltenHydraDynamicValue() { - - } - - public MotltenHydraDynamicValue(final MotltenHydraDynamicValue dynamicValue) { - } +enum MoltenHydraDynamicValue implements DynamicValue { + instance; @Override public int calculate(Game game, Ability source, Effect effect) { int count = 0; - for(Cost cost : source.getCosts()){ - if(cost instanceof RemoveAllCountersSourceCost){ - count += ((RemoveAllCountersSourceCost)cost).getAmount(); + for (Cost cost : source.getCosts()) { + if (cost instanceof RemoveAllCountersSourceCost) { + count += ((RemoveAllCountersSourceCost) cost).getRemovedCounters(); } } return count; } @Override - public MotltenHydraDynamicValue copy() { - return new MotltenHydraDynamicValue(this); + public MoltenHydraDynamicValue copy() { + return instance; } @Override @@ -146,4 +87,3 @@ class MotltenHydraDynamicValue implements DynamicValue { return "the number of +1/+1 counters removed this way"; } } - diff --git a/Mage.Sets/src/mage/cards/s/SageOfHours.java b/Mage.Sets/src/mage/cards/s/SageOfHours.java index ba80bfe4279..0230d1c0b85 100644 --- a/Mage.Sets/src/mage/cards/s/SageOfHours.java +++ b/Mage.Sets/src/mage/cards/s/SageOfHours.java @@ -1,36 +1,33 @@ - package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.RemoveAllCountersSourceCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.HeroicAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.SubType; import mage.counters.CounterType; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.game.turn.TurnMod; import mage.players.Player; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class SageOfHours extends CardImpl { public SageOfHours(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -40,8 +37,7 @@ public final class SageOfHours extends CardImpl { // Heroic - Whenever you cast a spell that targets Sage of Hours, put a +1/+1 counter on it. this.addAbility(new HeroicAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()))); // Remove all +1/+1 counters from Sage of Hours: For each five counters removed this way, take an extra turn after this one. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SageOfHoursEffect(), new SageOfHoursCost())); - + this.addAbility(new SimpleActivatedAbility(new SageOfHoursEffect(), new RemoveAllCountersSourceCost(CounterType.P1P1))); } public SageOfHours(final SageOfHours card) { @@ -54,49 +50,6 @@ public final class SageOfHours extends CardImpl { } } -class SageOfHoursCost extends CostImpl { - - private int removedCounters; - - public SageOfHoursCost() { - super(); - this.removedCounters = 0; - this.text = "Remove all +1/+1 counters from {this}"; - } - - public SageOfHoursCost(SageOfHoursCost cost) { - super(cost); - this.removedCounters = cost.removedCounters; - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(ability.getSourceId()); - if (permanent != null) { - this.removedCounters = permanent.getCounters(game).getCount(CounterType.P1P1); - if (this.removedCounters > 0) { - permanent.removeCounters(CounterType.P1P1.createInstance(this.removedCounters), game); - } - } - this.paid = true; - return true; - } - - @Override - public SageOfHoursCost copy() { - return new SageOfHoursCost(this); - } - - public int getRemovedCounters() { - return this.removedCounters; - } -} - class SageOfHoursEffect extends OneShotEffect { public SageOfHoursEffect() { @@ -119,8 +72,8 @@ class SageOfHoursEffect extends OneShotEffect { if (player != null) { int countersRemoved = 0; for (Cost cost : source.getCosts()) { - if (cost instanceof SageOfHoursCost) { - countersRemoved = ((SageOfHoursCost) cost).getRemovedCounters(); + if (cost instanceof RemoveAllCountersSourceCost) { + countersRemoved = ((RemoveAllCountersSourceCost) cost).getRemovedCounters(); } } int turns = countersRemoved / 5; diff --git a/Mage.Sets/src/mage/cards/t/TortureChamber.java b/Mage.Sets/src/mage/cards/t/TortureChamber.java index 30a60152cf3..18838fb37c4 100644 --- a/Mage.Sets/src/mage/cards/t/TortureChamber.java +++ b/Mage.Sets/src/mage/cards/t/TortureChamber.java @@ -1,11 +1,11 @@ package mage.cards.t; import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; -import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.RemoveAllCountersSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; @@ -14,10 +14,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.TargetController; import mage.counters.CounterType; import mage.game.Game; -import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; @@ -33,13 +32,19 @@ public final class TortureChamber extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // At the beginning of your upkeep, put a pain counter on Torture Chamber. - this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new AddCountersSourceEffect(CounterType.PAIN.createInstance()))); + this.addAbility(new BeginningOfUpkeepTriggeredAbility( + new AddCountersSourceEffect(CounterType.PAIN.createInstance()), TargetController.YOU, false + )); + // At the beginning of your end step, Torture Chamber deals damage to you equal to the number of pain counters on it. this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new TortureChamberEffect1(), false)); + // {1}, {tap}, Remove all pain counters from Torture Chamber: Torture Chamber deals damage to target creature equal to the number of pain counters removed this way. - SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TortureChamberEffect2(), new GenericManaCost(1)); + SimpleActivatedAbility ability = new SimpleActivatedAbility( + new TortureChamberEffect2(), new GenericManaCost(1) + ); ability.addCost(new TapSourceCost()); - ability.addCost(new TortureChamberCost()); + ability.addCost(new RemoveAllCountersSourceCost(CounterType.PAIN)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } @@ -54,49 +59,6 @@ public final class TortureChamber extends CardImpl { } } -class TortureChamberCost extends CostImpl { - - private int removedCounters; - - public TortureChamberCost() { - super(); - this.removedCounters = 0; - this.text = "Remove all pain counters from {this}"; - } - - public TortureChamberCost(TortureChamberCost cost) { - super(cost); - this.removedCounters = cost.removedCounters; - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(ability.getSourceId()); - if (permanent != null) { - this.removedCounters = permanent.getCounters(game).getCount(CounterType.PAIN); - if (this.removedCounters > 0) { - permanent.removeCounters(CounterType.PAIN.createInstance(this.removedCounters), game); - } - } - this.paid = true; - return true; - } - - @Override - public TortureChamberCost copy() { - return new TortureChamberCost(this); - } - - public int getRemovedCounters() { - return this.removedCounters; - } -} - class TortureChamberEffect1 extends OneShotEffect { public TortureChamberEffect1() { @@ -146,8 +108,8 @@ class TortureChamberEffect2 extends OneShotEffect { public boolean apply(Game game, Ability source) { int countersRemoved = 0; for (Cost cost : source.getCosts()) { - if (cost instanceof TortureChamberCost) { - countersRemoved = ((TortureChamberCost) cost).getRemovedCounters(); + if (cost instanceof RemoveAllCountersSourceCost) { + countersRemoved = ((RemoveAllCountersSourceCost) cost).getRemovedCounters(); } } Permanent permanent = game.getPermanent(source.getFirstTarget()); diff --git a/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java b/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java index dc3d414a5d5..fc5e0831ea2 100644 --- a/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java +++ b/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java @@ -1,16 +1,13 @@ - package mage.cards.v; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.CostImpl; +import mage.abilities.costs.common.RemoveAllCountersSourceCost; import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.SacrificeCostCreaturesPower; -import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; @@ -19,20 +16,19 @@ import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.SuperType; -import mage.constants.Zone; -import mage.counters.Counter; import mage.counters.CounterType; -import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + +import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT; + /** - * * @author LevelX2 */ public final class VishKalBloodArbiter extends CardImpl { @@ -47,18 +43,25 @@ public final class VishKalBloodArbiter extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + // Lifelink this.addAbility(LifelinkAbility.getInstance()); + // Sacrifice a creature: Put X +1/+1 counters on Vish Kal, Blood Arbiter, where X is the sacrificed creature's power. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, - new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), SacrificeCostCreaturesPower.instance, true), - new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)))); + this.addAbility(new SimpleActivatedAbility( + new AddCountersSourceEffect( + CounterType.P1P1.createInstance(), SacrificeCostCreaturesPower.instance, true + ), new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)) + )); + // Remove all +1/+1 counters from Vish Kal: Target creature gets -1/-1 until end of turn for each +1/+1 counter removed this way. - DynamicValue removedCounters = new SignInversionDynamicValue(new VishKalBloodArbiterDynamicValue()); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(removedCounters, removedCounters, Duration.EndOfTurn), new VishKalBloodArbiterCost(CounterType.P1P1.createInstance())); + Ability ability = new SimpleActivatedAbility(new BoostTargetEffect( + VishKalBloodArbiterDynamicValue.instance, + VishKalBloodArbiterDynamicValue.instance, + Duration.EndOfTurn, true + ), new RemoveAllCountersSourceCost(CounterType.P1P1)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - } public VishKalBloodArbiter(final VishKalBloodArbiter card) { @@ -71,75 +74,23 @@ public final class VishKalBloodArbiter extends CardImpl { } } -class VishKalBloodArbiterCost extends CostImpl { - - private int amount; - private String name; - - public VishKalBloodArbiterCost(Counter counter) { - this.name = counter.getName(); - this.amount = counter.getCount(); - this.text = "Remove all " + name + " counters from {this}"; - } - - public VishKalBloodArbiterCost(VishKalBloodArbiterCost cost) { - super(cost); - this.amount = cost.amount; - this.name = cost.name; - } - - @Override - public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { - return true; - } - - @Override - public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { - Permanent permanent = game.getPermanent(sourceId); - if (permanent != null) { - this.amount = permanent.getCounters(game).getCount(name); - permanent.removeCounters(name, amount, game); - this.paid = true; - } else { - this.amount = 0; - } - return paid; - } - - @Override - public VishKalBloodArbiterCost copy() { - return new VishKalBloodArbiterCost(this); - } - - public int getAmount() { - return amount; - } - -} - -class VishKalBloodArbiterDynamicValue implements DynamicValue { - - public VishKalBloodArbiterDynamicValue() { - - } - - public VishKalBloodArbiterDynamicValue(final VishKalBloodArbiterDynamicValue dynamicValue) { - } +enum VishKalBloodArbiterDynamicValue implements DynamicValue { + instance; @Override public int calculate(Game game, Ability source, Effect effect) { int count = 0; for (Cost cost : source.getCosts()) { - if (cost instanceof VishKalBloodArbiterCost) { - count += ((VishKalBloodArbiterCost) cost).getAmount(); + if (cost instanceof RemoveAllCountersSourceCost) { + count += ((RemoveAllCountersSourceCost) cost).getRemovedCounters(); } } - return count; + return -count; } @Override public VishKalBloodArbiterDynamicValue copy() { - return new VishKalBloodArbiterDynamicValue(this); + return instance; } @Override diff --git a/Mage/src/main/java/mage/abilities/costs/common/RemoveAllCountersSourceCost.java b/Mage/src/main/java/mage/abilities/costs/common/RemoveAllCountersSourceCost.java new file mode 100644 index 00000000000..0e3ed63f617 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/costs/common/RemoveAllCountersSourceCost.java @@ -0,0 +1,57 @@ +package mage.abilities.costs.common; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.CostImpl; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public class RemoveAllCountersSourceCost extends CostImpl { + + private final CounterType counterType; + private int removedCounters = 0; + + public RemoveAllCountersSourceCost(CounterType counterType) { + this.counterType = counterType; + this.text = "Remove all " + counterType.getName() + " counters from {this}"; + } + + public RemoveAllCountersSourceCost(RemoveAllCountersSourceCost cost) { + super(cost); + this.counterType = cost.counterType; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + Permanent permanent = game.getPermanent(sourceId); + return permanent != null; + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + Permanent permanent = game.getPermanent(ability.getSourceId()); + if (permanent != null) { + this.removedCounters = permanent.getCounters(game).getCount(counterType); + if (this.removedCounters > 0) { + permanent.removeCounters(counterType.createInstance(this.removedCounters), game); + } + } + this.paid = true; + return true; + } + + @Override + public RemoveAllCountersSourceCost copy() { + return new RemoveAllCountersSourceCost(this); + } + + public int getRemovedCounters() { + return removedCounters; + } +}