diff --git a/Mage.Sets/src/mage/cards/a/AfiyaGrove.java b/Mage.Sets/src/mage/cards/a/AfiyaGrove.java index cf3a3a03c1b..1d643f93646 100644 --- a/Mage.Sets/src/mage/cards/a/AfiyaGrove.java +++ b/Mage.Sets/src/mage/cards/a/AfiyaGrove.java @@ -1,27 +1,25 @@ - package mage.cards.a; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.StateTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.EntersBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.MoveCountersFromSourceToTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author TheElk801 @@ -35,7 +33,7 @@ public final class AfiyaGrove extends CardImpl { this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(3)), "with three +1/+1 counters on it")); // At the beginning of your upkeep, move a +1/+1 counter from Afiya Grove onto target creature. - Ability ability = new BeginningOfUpkeepTriggeredAbility(new MoveCounterToTargetFromSourceEffect(), TargetController.YOU, false); + Ability ability = new BeginningOfUpkeepTriggeredAbility(new MoveCountersFromSourceToTargetEffect(), TargetController.YOU, false); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -53,39 +51,6 @@ public final class AfiyaGrove extends CardImpl { } } -class MoveCounterToTargetFromSourceEffect extends OneShotEffect { - - public MoveCounterToTargetFromSourceEffect() { - super(Outcome.Benefit); - this.staticText = "move a +1/+1 counter from {this} onto target creature"; - } - - private MoveCounterToTargetFromSourceEffect(final MoveCounterToTargetFromSourceEffect effect) { - super(effect); - } - - @Override - public MoveCounterToTargetFromSourceEffect copy() { - return new MoveCounterToTargetFromSourceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - Permanent sourceObject = game.getPermanent(source.getSourceId()); - if (sourceObject != null && controller != null) { - Permanent toPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (toPermanent != null && sourceObject.getCounters(game).getCount(CounterType.P1P1) > 0) { - sourceObject.removeCounters(CounterType.P1P1.createInstance(), source, game); - toPermanent.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game); - game.informPlayers("Moved a +1/+1 counter from " + sourceObject.getLogName() + " to " + toPermanent.getLogName()); - } - return true; - } - return false; - } -} - class AfiyaGroveNoCountersAbility extends StateTriggeredAbility { public AfiyaGroveNoCountersAbility() { @@ -104,10 +69,7 @@ class AfiyaGroveNoCountersAbility extends StateTriggeredAbility { @Override public boolean checkTrigger(GameEvent event, Game game) { Permanent permanent = game.getPermanent(getSourceId()); - if (permanent != null && permanent.getCounters(game).getCount(CounterType.P1P1) == 0) { - return true; - } - return false; + return permanent != null && permanent.getCounters(game).getCount(CounterType.P1P1) == 0; } @Override diff --git a/Mage.Sets/src/mage/cards/e/ExplorersCache.java b/Mage.Sets/src/mage/cards/e/ExplorersCache.java new file mode 100644 index 00000000000..0e21505a8b7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/e/ExplorersCache.java @@ -0,0 +1,54 @@ +package mage.cards.e; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.MoveCountersFromSourceToTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.filter.StaticFilters; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author xenohedron + */ +public final class ExplorersCache extends CardImpl { + + public ExplorersCache(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{G}"); + + // Explorer's Cache enters the battlefield with two +1/+1 counters on it. + this.addAbility(new EntersBattlefieldAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), + "with two +1/+1 counters on it" + )); + + // Whenever a creature you control with a +1/+1 counter on it dies, put a +1/+1 counter on Explorer's Cache. + this.addAbility(new DiesCreatureTriggeredAbility( + new AddCountersSourceEffect(CounterType.P1P1.createInstance()), + false, + StaticFilters.FILTER_A_CONTROLLED_CREATURE_P1P1)); + + // {T}: Move a +1/+1 counter from Explorer's Cache onto target creature. Activate only as a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility(new MoveCountersFromSourceToTargetEffect(), new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + } + + private ExplorersCache(final ExplorersCache card) { + super(card); + } + + @Override + public ExplorersCache copy() { + return new ExplorersCache(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GladehartCavalry.java b/Mage.Sets/src/mage/cards/g/GladehartCavalry.java index 81470b2efb9..4799f6c7fcc 100644 --- a/Mage.Sets/src/mage/cards/g/GladehartCavalry.java +++ b/Mage.Sets/src/mage/cards/g/GladehartCavalry.java @@ -1,21 +1,16 @@ - package mage.cards.g; -import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.DiesCreatureTriggeredAbility; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.keyword.SupportAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Zone; -import mage.counters.CounterType; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; +import mage.filter.StaticFilters; + +import java.util.UUID; /** * @@ -34,7 +29,10 @@ public final class GladehartCavalry extends CardImpl { this.addAbility(new SupportAbility(this, 6)); // Whenever a creature you control with a +1/+1 counter on it dies, you gain 2 life. - this.addAbility(new GladehartCavalryTriggeredAbility()); + this.addAbility(new DiesCreatureTriggeredAbility( + new GainLifeEffect(2), + false, + StaticFilters.FILTER_A_CONTROLLED_CREATURE_P1P1)); } private GladehartCavalry(final GladehartCavalry card) { @@ -46,40 +44,3 @@ public final class GladehartCavalry extends CardImpl { return new GladehartCavalry(this); } } - -class GladehartCavalryTriggeredAbility extends TriggeredAbilityImpl { - - public GladehartCavalryTriggeredAbility() { - super(Zone.BATTLEFIELD, new GainLifeEffect(2)); - setTriggerPhrase("Whenever a creature you control with a +1/+1 counter on it dies, "); - } - - private GladehartCavalryTriggeredAbility(final GladehartCavalryTriggeredAbility ability) { - super(ability); - } - - @Override - public GladehartCavalryTriggeredAbility copy() { - return new GladehartCavalryTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - ZoneChangeEvent zoneChangeEvent = (ZoneChangeEvent) event; - if (zoneChangeEvent.isDiesEvent()) { - Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (permanent != null - && permanent.isControlledBy(this.getControllerId()) - && permanent.isCreature(game) - && permanent.getCounters(game).getCount(CounterType.P1P1) > 0) { - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SimicFluxmage.java b/Mage.Sets/src/mage/cards/s/SimicFluxmage.java index a2e3bf7499b..743c5c13b24 100644 --- a/Mage.Sets/src/mage/cards/s/SimicFluxmage.java +++ b/Mage.Sets/src/mage/cards/s/SimicFluxmage.java @@ -1,25 +1,21 @@ - package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.MoveCountersFromSourceToTargetEffect; import mage.abilities.keyword.EvolveAbility; 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.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -38,7 +34,7 @@ public final class SimicFluxmage extends CardImpl { this.addAbility(new EvolveAbility()); // 1{U}, {T}: Move a +1/+1 counter from Simic Fluxmage onto target creature. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoveCounterFromSourceToTargetEffect(),new ManaCostsImpl<>("{1}{U}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoveCountersFromSourceToTargetEffect(),new ManaCostsImpl<>("{1}{U}")); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -54,34 +50,3 @@ public final class SimicFluxmage extends CardImpl { return new SimicFluxmage(this); } } - -class MoveCounterFromSourceToTargetEffect extends OneShotEffect { - - public MoveCounterFromSourceToTargetEffect() { - super(Outcome.Detriment); - this.staticText = "Move a +1/+1 counter from {this} onto target creature"; - } - - private MoveCounterFromSourceToTargetEffect(final MoveCounterFromSourceToTargetEffect effect) { - super(effect); - } - - @Override - public MoveCounterFromSourceToTargetEffect copy() { - return new MoveCounterFromSourceToTargetEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent != null && sourcePermanent.getCounters(game).getCount(CounterType.P1P1) > 0) { - Permanent targetPermanent = game.getPermanent(targetPointer.getFirst(game, source)); - if (targetPermanent != null) { - sourcePermanent.removeCounters(CounterType.P1P1.createInstance(), source, game); - targetPermanent.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/s/SteelDromedary.java b/Mage.Sets/src/mage/cards/s/SteelDromedary.java index aec5cae1d8f..28cbc3a922c 100644 --- a/Mage.Sets/src/mage/cards/s/SteelDromedary.java +++ b/Mage.Sets/src/mage/cards/s/SteelDromedary.java @@ -8,19 +8,16 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; import mage.abilities.effects.common.TapSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.MoveCountersFromSourceToTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.TargetController; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -53,7 +50,7 @@ public final class SteelDromedary extends CardImpl { // At the beginning of combat on your turn, you may move a +1/+1 counter from Steel Dromedary onto target creature. ability = new BeginningOfCombatTriggeredAbility( - new SteelDromedaryEffect(), TargetController.YOU, true + new MoveCountersFromSourceToTargetEffect(), TargetController.YOU, true ); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -68,34 +65,3 @@ public final class SteelDromedary extends CardImpl { return new SteelDromedary(this); } } - -class SteelDromedaryEffect extends OneShotEffect { - - SteelDromedaryEffect() { - super(Outcome.Benefit); - staticText = "you may move a +1/+1 counter from {this} onto target creature"; - } - - private SteelDromedaryEffect(final SteelDromedaryEffect effect) { - super(effect); - } - - @Override - public SteelDromedaryEffect copy() { - return new SteelDromedaryEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = source.getSourcePermanentIfItStillExists(game); - Permanent creature = game.getPermanent(source.getFirstTarget()); - if (permanent != null - && creature != null - && permanent.getCounters(game).getCount(CounterType.P1P1) > 0 - && creature.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game)) { - permanent.removeCounters(CounterType.P1P1.createInstance(), source, game); - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/w/WeaponRack.java b/Mage.Sets/src/mage/cards/w/WeaponRack.java index 30059675be6..8fad641d87a 100644 --- a/Mage.Sets/src/mage/cards/w/WeaponRack.java +++ b/Mage.Sets/src/mage/cards/w/WeaponRack.java @@ -4,16 +4,13 @@ import mage.abilities.Ability; import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.MoveCountersFromSourceToTargetEffect; 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.target.common.TargetCreaturePermanent; import java.util.UUID; @@ -34,7 +31,7 @@ public final class WeaponRack extends CardImpl { // {T}: Move a +1/+1 counter from Weapon Rack onto target creature. Activate this ability only any time you could cast a sorcery. Ability ability = new ActivateAsSorceryActivatedAbility( - Zone.BATTLEFIELD, new WeaponRackEffect(), new TapSourceCost() + Zone.BATTLEFIELD, new MoveCountersFromSourceToTargetEffect(), new TapSourceCost() ); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -49,34 +46,3 @@ public final class WeaponRack extends CardImpl { return new WeaponRack(this); } } - -class WeaponRackEffect extends OneShotEffect { - - WeaponRackEffect() { - super(Outcome.Benefit); - staticText = "move a +1/+1 counter from {this} onto target creature"; - } - - private WeaponRackEffect(final WeaponRackEffect effect) { - super(effect); - } - - @Override - public WeaponRackEffect copy() { - return new WeaponRackEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent sourcePermanent = game.getPermanent(source.getSourceId()); - if (sourcePermanent == null || !sourcePermanent.getCounters(game).containsKey(CounterType.P1P1)) { - return false; - } - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent == null || !permanent.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game)) { - return false; - } - sourcePermanent.removeCounters(CounterType.P1P1.createInstance(), source, game); - return true; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index 1e2fd14011f..f7a8d9b2cdd 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java @@ -46,6 +46,7 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Dinotomaton", 144, Rarity.COMMON, mage.cards.d.Dinotomaton.class)); cards.add(new SetCardInfo("Earthshaker Dreadmaw", 183, Rarity.UNCOMMON, mage.cards.e.EarthshakerDreadmaw.class)); cards.add(new SetCardInfo("Enterprising Scallywag", 148, Rarity.UNCOMMON, mage.cards.e.EnterprisingScallywag.class)); + cards.add(new SetCardInfo("Explorer's Cache", 184, Rarity.UNCOMMON, mage.cards.e.ExplorersCache.class)); cards.add(new SetCardInfo("Forest", 401, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Geological Appraiser", 150, Rarity.UNCOMMON, mage.cards.g.GeologicalAppraiser.class)); cards.add(new SetCardInfo("Get Lost", 14, Rarity.RARE, mage.cards.g.GetLost.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/MoveCountersFromSourceToTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/MoveCountersFromSourceToTargetEffect.java new file mode 100644 index 00000000000..952b20470f8 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/MoveCountersFromSourceToTargetEffect.java @@ -0,0 +1,77 @@ +package mage.abilities.effects.common.counter; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * @author xenohedron + */ +public class MoveCountersFromSourceToTargetEffect extends OneShotEffect { + + private final CounterType counterType; + private final int amount; + + /** + * Move a +1/+1 counter from {this} onto target + */ + public MoveCountersFromSourceToTargetEffect() { + this(CounterType.P1P1); + } + + /** + * Move a counter of the specified type from {this} onto target + */ + public MoveCountersFromSourceToTargetEffect(CounterType counterType) { + this(counterType, 1); + } + + /** + * Move a specific amount of counters of the specified type from {this} onto target + */ + public MoveCountersFromSourceToTargetEffect(CounterType counterType, int amount) { + super(Outcome.Neutral); + this.counterType = counterType; + this.amount = amount; + } + + protected MoveCountersFromSourceToTargetEffect(final MoveCountersFromSourceToTargetEffect effect) { + super(effect); + this.counterType = effect.counterType; + this.amount = effect.amount; + } + + @Override + public MoveCountersFromSourceToTargetEffect copy() { + return new MoveCountersFromSourceToTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game); + Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + if (sourcePermanent == null || targetPermanent == null + || sourcePermanent.getId().equals(targetPermanent.getId()) + || sourcePermanent.getCounters(game).getCount(counterType) < amount + || !targetPermanent.addCounters(counterType.createInstance(amount), source.getControllerId(), source, game)) { + return false; + } + sourcePermanent.removeCounters(counterType.createInstance(amount), source, game); + return true; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "move " + CardUtil.numberToText(amount, "a") + ' ' + counterType.getName() + + (amount > 1 ? " counters" : " counter") + " from {this} onto " + + getTargetPointer().describeTargets(mode.getTargets(), "that creature"); + } +}