From cf17d026571e961ddc0d27b7615e5238db38391a Mon Sep 17 00:00:00 2001 From: MTGfan Date: Thu, 22 Dec 2016 15:58:03 -0500 Subject: [PATCH] CyclopeanTomb: updated to track what lands it is putting counters on --- Mage.Sets/src/mage/cards/c/CyclopeanTomb.java | 110 ++++++++++++++++-- 1 file changed, 102 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java b/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java index ad2e02a2ed..8626b5636a 100644 --- a/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java +++ b/Mage.Sets/src/mage/cards/c/CyclopeanTomb.java @@ -27,12 +27,15 @@ */ package mage.cards.c; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; +import mage.abilities.condition.Condition; import mage.abilities.condition.common.IsStepCondition; -import mage.abilities.condition.common.PermanentHasCounterCondition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.decorator.ConditionalActivatedAbility; @@ -42,6 +45,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.common.counter.RemoveAllCountersTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -53,6 +57,7 @@ import mage.constants.SubLayer; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.CounterPredicate; @@ -61,6 +66,7 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetLandPermanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -69,6 +75,7 @@ import mage.target.common.TargetLandPermanent; public class CyclopeanTomb extends CardImpl { private static final FilterLandPermanent filter = new FilterLandPermanent(); + public List lands = new ArrayList<>(); static { filter.add(Predicates.not(new SubtypePredicate("Swamp"))); @@ -84,8 +91,10 @@ public class CyclopeanTomb extends CardImpl { ability.addTarget(new TargetLandPermanent(filter)); ability.addEffect(new BecomeSwampEffect(Duration.Custom, false, true, "Swamp")); this.addAbility(ability); + //add the targets UUID to an array to track which specific lands the instance of Cyclopean Tomb added a mire counter to. + lands.add(ability.getTargets().getFirstTarget()); // When Cyclopean Tomb is put into a graveyard from the battlefield, at the beginning of each of your upkeeps for the rest of the game, remove all mire counters from a land that a mire counter was put onto with Cyclopean Tomb but that a mire counter has not been removed from with Cyclopean Tomb. - Effect effect = new CreateDelayedTriggeredAbilityEffect(new CycleDelayedTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect(new CycleDelayedTriggeredAbility(lands)); effect.setText("at the beginning of each of your upkeeps for the rest of the game, remove all mire counters from a land that a mire counter was put onto with {this} but that a mire counter has not been removed from with {this}."); this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(effect)); } @@ -132,8 +141,8 @@ class BecomeSwampEffect extends BecomesBasicLandTargetEffect { class CycleDelayedTriggeredAbility extends DelayedTriggeredAbility { - CycleDelayedTriggeredAbility() { - super(new CyclopeanTombEffect(), Duration.OneUse, true, false); + CycleDelayedTriggeredAbility(List lands) { + super(new CyclopeanTombEffect(lands), Duration.OneUse, true, false); } CycleDelayedTriggeredAbility(CycleDelayedTriggeredAbility ability) { @@ -158,14 +167,16 @@ class CycleDelayedTriggeredAbility extends DelayedTriggeredAbility { class CyclopeanTombEffect extends OneShotEffect { - private static final FilterLandPermanent mireFilter = new FilterLandPermanent(); - + List lands = new ArrayList<>(); + public static final FilterLandPermanent mireFilter = new FilterLandPermanent(); + static { mireFilter.add(new CounterPredicate(CounterType.MIRE)); } - public CyclopeanTombEffect() { + public CyclopeanTombEffect(List lands) { super(Outcome.Benefit); + this.lands = lands; this.staticText = "at the beginning of each of your upkeeps for the rest of the game, remove all mire counters from a land that a mire counter was put onto with {this} but that a mire counter has not been removed from with {this}."; } @@ -187,11 +198,94 @@ class CyclopeanTombEffect extends OneShotEffect { *Remove all counters from target code goes here. Created a RemoveAllCountersTargetEffect for that. * */ + new ChooseLandEffect(lands).apply(game, source); + Effect effect = new RemoveAllCountersTargetEffect(CounterType.MIRE); + effect.setTargetPointer(new FixedTarget((UUID) game.getState().getValue(source.getSourceId().toString() + "_land"))); + effect.apply(game, source); //CyclopianTombEffect and CycleDelayedTriggeredAbility will maintain a loop //as long as there are one or more mire counters left to be removed - new ConditionalOneShotEffect(new CreateDelayedTriggeredAbilityEffect(new CycleDelayedTriggeredAbility(), false), new PermanentHasCounterCondition(CounterType.MIRE, 0, new FilterLandPermanent(), PermanentHasCounterCondition.CountType.MORE_THAN, true)).apply(game, source); + new ConditionalOneShotEffect(new CreateDelayedTriggeredAbilityEffect(new CycleDelayedTriggeredAbility(lands), false), new CyclopeanTombCounterCondition(lands)).apply(game, source); return true; } return false; } } + +class CyclopeanTombCounterCondition implements Condition { + + private List lands; + + public CyclopeanTombCounterCondition(List lands) { + this.lands = lands; + } + + @Override + public boolean apply(Game game, Ability source) { + List permanents = game.getBattlefield().getAllActivePermanents(CyclopeanTombEffect.mireFilter, game); + for (UUID landId : lands) { + for(Permanent permanent : permanents) { + if(landId.equals(permanent.getId())) { + return permanent.getCounters(game).getCount(CounterType.MIRE) > 0; + } + } + } + return false; + } +} + +class ChooseLandEffect extends OneShotEffect { + + private List lands; + + public ChooseLandEffect(List lands) { + super(Outcome.Neutral); + this.lands = lands; + this.staticText = "choose a land that a mire counter was put onto with Cyclopean Tomb but that a mire counter has not been removed from with Cyclopean Tomb"; + } + + public ChooseLandEffect(final ChooseLandEffect effect) { + super(effect); + } + + @Override + public ChooseLandEffect copy() { + return new ChooseLandEffect(this); + } + //UUID chosenLand = ; use with addTarget or setTargetPointer + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getObject(source.getSourceId()); + FilterLandPermanent filter = new FilterLandPermanent(); + filter.add(new LandIdPredicate(lands)); + if(controller != null){ + TargetLandPermanent target = new TargetLandPermanent(filter); + if (controller.choose(this.outcome, target, source.getSourceId(), game)) { + Permanent chosenLand = game.getPermanent(target.getFirstTarget()); + if(chosenLand != null) { + game.getState().setValue(mageObject.getId() + "_land", target.getFirstTarget()); + return true; + } + } + } + return false; + } +} + +class LandIdPredicate implements Predicate { + + private List lands; + + public LandIdPredicate(List lands) { + this.lands = lands; + } + @Override + public boolean apply(Permanent input, Game game) { + for(UUID landId : lands){ + return input.getId().equals(landId); + } + return false; + } +} + +