CyclopeanTomb: updated to track what lands it is putting counters on

This commit is contained in:
MTGfan 2016-12-22 15:58:03 -05:00
parent dc2e4569db
commit cf17d02657

View file

@ -27,12 +27,15 @@
*/ */
package mage.cards.c; package mage.cards.c;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility; import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.IsStepCondition; import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.condition.common.PermanentHasCounterCondition;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.decorator.ConditionalActivatedAbility; 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.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect; import mage.abilities.effects.common.continuous.BecomesBasicLandTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.effects.common.counter.RemoveAllCountersTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -53,6 +57,7 @@ import mage.constants.SubLayer;
import mage.constants.Zone; import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.common.FilterLandPermanent; import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.CounterPredicate; import mage.filter.predicate.permanent.CounterPredicate;
@ -61,6 +66,7 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -69,6 +75,7 @@ import mage.target.common.TargetLandPermanent;
public class CyclopeanTomb extends CardImpl { public class CyclopeanTomb extends CardImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent(); private static final FilterLandPermanent filter = new FilterLandPermanent();
public List<UUID> lands = new ArrayList<>();
static { static {
filter.add(Predicates.not(new SubtypePredicate("Swamp"))); filter.add(Predicates.not(new SubtypePredicate("Swamp")));
@ -84,8 +91,10 @@ public class CyclopeanTomb extends CardImpl {
ability.addTarget(new TargetLandPermanent(filter)); ability.addTarget(new TargetLandPermanent(filter));
ability.addEffect(new BecomeSwampEffect(Duration.Custom, false, true, "Swamp")); ability.addEffect(new BecomeSwampEffect(Duration.Custom, false, true, "Swamp"));
this.addAbility(ability); 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. // 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}."); 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)); this.addAbility(new PutIntoGraveFromBattlefieldSourceTriggeredAbility(effect));
} }
@ -132,8 +141,8 @@ class BecomeSwampEffect extends BecomesBasicLandTargetEffect {
class CycleDelayedTriggeredAbility extends DelayedTriggeredAbility { class CycleDelayedTriggeredAbility extends DelayedTriggeredAbility {
CycleDelayedTriggeredAbility() { CycleDelayedTriggeredAbility(List<UUID> lands) {
super(new CyclopeanTombEffect(), Duration.OneUse, true, false); super(new CyclopeanTombEffect(lands), Duration.OneUse, true, false);
} }
CycleDelayedTriggeredAbility(CycleDelayedTriggeredAbility ability) { CycleDelayedTriggeredAbility(CycleDelayedTriggeredAbility ability) {
@ -158,14 +167,16 @@ class CycleDelayedTriggeredAbility extends DelayedTriggeredAbility {
class CyclopeanTombEffect extends OneShotEffect { class CyclopeanTombEffect extends OneShotEffect {
private static final FilterLandPermanent mireFilter = new FilterLandPermanent(); List<UUID> lands = new ArrayList<>();
public static final FilterLandPermanent mireFilter = new FilterLandPermanent();
static { static {
mireFilter.add(new CounterPredicate(CounterType.MIRE)); mireFilter.add(new CounterPredicate(CounterType.MIRE));
} }
public CyclopeanTombEffect() { public CyclopeanTombEffect(List<UUID> lands) {
super(Outcome.Benefit); 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}."; 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. *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 //CyclopianTombEffect and CycleDelayedTriggeredAbility will maintain a loop
//as long as there are one or more mire counters left to be removed //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 true;
} }
return false; return false;
} }
} }
class CyclopeanTombCounterCondition implements Condition {
private List<UUID> lands;
public CyclopeanTombCounterCondition(List<UUID> lands) {
this.lands = lands;
}
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> 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<UUID> lands;
public ChooseLandEffect(List<UUID> 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<Permanent> {
private List<UUID> lands;
public LandIdPredicate(List<UUID> lands) {
this.lands = lands;
}
@Override
public boolean apply(Permanent input, Game game) {
for(UUID landId : lands){
return input.getId().equals(landId);
}
return false;
}
}