[C21] Implemented Yedora, Grave Gardener

This commit is contained in:
Evan Kranzler 2021-04-28 09:21:39 -04:00
parent 7778e867f8
commit bf2e90feae
9 changed files with 193 additions and 87 deletions

View file

@ -100,7 +100,7 @@ class ChooseACreature extends OneShotEffect {
class MetamorphicAlterationEffect extends ContinuousEffectImpl { class MetamorphicAlterationEffect extends ContinuousEffectImpl {
public MetamorphicAlterationEffect() { public MetamorphicAlterationEffect() {
super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.Copy); super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.Copy);
this.staticText = "Enchanted creature is a copy of the chosen creature."; this.staticText = "Enchanted creature is a copy of the chosen creature.";
} }

View file

@ -1,14 +1,18 @@
package mage.cards.t; package mage.cards.t;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
import mage.cards.*; import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.*; import mage.constants.*;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
@ -17,9 +21,10 @@ import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTargets;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
/** /**
* @author TheElk801 * @author TheElk801
@ -38,9 +43,7 @@ public final class TezzeretCruelMachinist extends CardImpl {
// 0: Until your next turn, target artifact you control becomes a 5/5 creature in addition to its other types. // 0: Until your next turn, target artifact you control becomes a 5/5 creature in addition to its other types.
Ability ability = new LoyaltyAbility(new AddCardTypeTargetEffect( Ability ability = new LoyaltyAbility(new AddCardTypeTargetEffect(
Duration.UntilYourNextTurn, Duration.UntilYourNextTurn, CardType.ARTIFACT, CardType.CREATURE
CardType.ARTIFACT,
CardType.CREATURE
).setText("Until your next turn, target artifact you control becomes an artifact creature"), 0); ).setText("Until your next turn, target artifact you control becomes an artifact creature"), 0);
ability.addEffect(new SetPowerToughnessTargetEffect( ability.addEffect(new SetPowerToughnessTargetEffect(
5, 5, Duration.UntilYourNextTurn 5, 5, Duration.UntilYourNextTurn
@ -85,41 +88,30 @@ class TezzeretCruelMachinistEffect extends OneShotEffect {
return false; return false;
} }
Target target = new TargetCardInHand(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD); Target target = new TargetCardInHand(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD);
if (!player.choose(outcome, target, source.getSourceId(), game)) { player.choose(outcome, target, source.getSourceId(), game);
Cards cardsToMove = new CardsImpl(target.getTargets());
if (cardsToMove.isEmpty()) {
return false; return false;
} }
Cards cardsToMove = new CardsImpl(); game.addEffect(new TezzeretCruelMachinistCardTypeEffect().setTargetPointer(new FixedTargets(
cardsToMove
for (UUID cardId : target.getTargets()) { .getCards(game)
Card card = game.getCard(cardId); .stream()
if (card == null) { .map(card -> new MageObjectReference(card, game, 1))
continue; .collect(Collectors.toSet()), game
} )), source);
cardsToMove.add(card); player.moveCards(
cardsToMove.getCards(game), Zone.BATTLEFIELD, source, game,
ContinuousEffect effectCardType = new TezzeretCruelMachinistCardTypeEffect(); false, true, true, null
effectCardType.setTargetPointer(new FixedTarget( );
card.getId(), return true;
card.getZoneChangeCounter(game) + 1
));
game.addEffect(effectCardType, source);
ContinuousEffect effectPowerToughness = new TezzeretCruelMachinistPowerToughnessEffect();
effectPowerToughness.setTargetPointer(new FixedTarget(
card.getId(),
card.getZoneChangeCounter(game) + 1
));
game.addEffect(effectPowerToughness, source);
}
return player.moveCards(cardsToMove.getCards(game), Zone.BATTLEFIELD, source, game, false, true, true, null);
} }
} }
class TezzeretCruelMachinistCardTypeEffect extends AddCardTypeTargetEffect { class TezzeretCruelMachinistCardTypeEffect extends ContinuousEffectImpl {
public TezzeretCruelMachinistCardTypeEffect() { public TezzeretCruelMachinistCardTypeEffect() {
super(Duration.WhileOnBattlefield, CardType.ARTIFACT, CardType.CREATURE); super(Duration.Custom, Layer.CopyEffects_1, SubLayer.FaceDownEffects_1b, Outcome.Neutral);
} }
public TezzeretCruelMachinistCardTypeEffect(final TezzeretCruelMachinistCardTypeEffect effect) { public TezzeretCruelMachinistCardTypeEffect(final TezzeretCruelMachinistCardTypeEffect effect) {
@ -132,53 +124,26 @@ class TezzeretCruelMachinistCardTypeEffect extends AddCardTypeTargetEffect {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
boolean flag = false;
for (UUID targetId : targetPointer.getTargets(game, source)) { for (UUID targetId : targetPointer.getTargets(game, source)) {
Permanent target = game.getPermanent(targetId); Permanent target = game.getPermanent(targetId);
if (target != null if (target == null || !target.isFaceDown(game)) {
&& target.isFaceDown(game)) { continue;
switch (layer) { }
case TypeChangingEffects_4: flag = true;
target.getSuperType().clear(); target.getSuperType().clear();
target.getCardType().clear(); target.getCardType().clear();
target.removeAllSubTypes(game); target.removeAllSubTypes(game);
target.addCardType(CardType.ARTIFACT); target.addCardType(CardType.ARTIFACT);
target.addCardType(CardType.CREATURE); target.addCardType(CardType.CREATURE);
break;
}
return true;
}
}
return false;
}
}
class TezzeretCruelMachinistPowerToughnessEffect extends SetPowerToughnessTargetEffect {
public TezzeretCruelMachinistPowerToughnessEffect() {
super(5, 5, Duration.WhileOnBattlefield);
}
public TezzeretCruelMachinistPowerToughnessEffect(final TezzeretCruelMachinistPowerToughnessEffect effect) {
super(effect);
}
@Override
public TezzeretCruelMachinistPowerToughnessEffect copy() {
return new TezzeretCruelMachinistPowerToughnessEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent target = game.getPermanent(targetId);
if (target != null
&& target.isFaceDown(game)) {
target.getPower().setValue(5); target.getPower().setValue(5);
target.getToughness().setValue(5); target.getToughness().setValue(5);
}
if (!flag) {
discard();
return false;
}
return true; return true;
} }
} }
return false;
}
}

View file

@ -0,0 +1,129 @@
package mage.cards.y;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AnotherPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class YedoraGraveGardener extends CardImpl {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent("another nontoken creature you control");
static {
filter.add(Predicates.not(TokenPredicate.instance));
filter.add(AnotherPredicate.instance);
}
public YedoraGraveGardener(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.TREEFOLK);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Whenever another nontoken creature you control dies, you may return it to the battlefield face down under its owner's control. It's a Forest land.
this.addAbility(new DiesCreatureTriggeredAbility(
new YedoraGraveGardenerEffect(), true, filter, true
));
}
private YedoraGraveGardener(final YedoraGraveGardener card) {
super(card);
}
@Override
public YedoraGraveGardener copy() {
return new YedoraGraveGardener(this);
}
}
class YedoraGraveGardenerEffect extends OneShotEffect {
YedoraGraveGardenerEffect() {
super(Outcome.Benefit);
staticText = "you may return it to the battlefield face down under its owner's control. " +
"It's a Forest land. <i>(It has no other types or abilities.)</i>";
}
private YedoraGraveGardenerEffect(final YedoraGraveGardenerEffect effect) {
super(effect);
}
@Override
public YedoraGraveGardenerEffect copy() {
return new YedoraGraveGardenerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (player == null || card == null) {
return false;
}
game.addEffect(new YedoraGraveGardenerContinuousEffect().setTargetPointer(
new FixedTarget(new MageObjectReference(card, game, 1))
), source);
player.moveCards(
card, Zone.BATTLEFIELD, source, game,
false, true, true, null
);
return true;
}
}
class YedoraGraveGardenerContinuousEffect extends ContinuousEffectImpl {
public YedoraGraveGardenerContinuousEffect() {
super(Duration.Custom, Layer.CopyEffects_1, SubLayer.FaceDownEffects_1b, Outcome.Neutral);
}
public YedoraGraveGardenerContinuousEffect(final YedoraGraveGardenerContinuousEffect effect) {
super(effect);
}
@Override
public YedoraGraveGardenerContinuousEffect copy() {
return new YedoraGraveGardenerContinuousEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(targetPointer.getFirst(game, source));
if (target == null || !target.isFaceDown(game)) {
discard();
return false;
}
target.getSuperType().clear();
target.getCardType().clear();
target.removeAllSubTypes(game);
target.addCardType(CardType.LAND);
target.addSubType(game, SubType.FOREST);
target.removeAllAbilities(source.getSourceId(), game);
target.addAbility(new GreenManaAbility());
return true;
}
}

View file

@ -345,6 +345,7 @@ public final class Commander2021Edition extends ExpansionSet {
cards.add(new SetCardInfo("Windborn Muse", 111, Rarity.RARE, mage.cards.w.WindbornMuse.class)); cards.add(new SetCardInfo("Windborn Muse", 111, Rarity.RARE, mage.cards.w.WindbornMuse.class));
cards.add(new SetCardInfo("Witch's Clinic", 81, Rarity.RARE, mage.cards.w.WitchsClinic.class)); cards.add(new SetCardInfo("Witch's Clinic", 81, Rarity.RARE, mage.cards.w.WitchsClinic.class));
cards.add(new SetCardInfo("Yavimaya Coast", 409, Rarity.RARE, mage.cards.y.YavimayaCoast.class)); cards.add(new SetCardInfo("Yavimaya Coast", 409, Rarity.RARE, mage.cards.y.YavimayaCoast.class));
cards.add(new SetCardInfo("Yedora, Grave Gardener", 70, Rarity.RARE, mage.cards.y.YedoraGraveGardener.class));
cards.add(new SetCardInfo("Zaffai, Thunder Conductor", 4, Rarity.MYTHIC, mage.cards.z.ZaffaiThunderConductor.class)); cards.add(new SetCardInfo("Zaffai, Thunder Conductor", 4, Rarity.MYTHIC, mage.cards.z.ZaffaiThunderConductor.class));
cards.add(new SetCardInfo("Zetalpa, Primal Dawn", 112, Rarity.RARE, mage.cards.z.ZetalpaPrimalDawn.class)); cards.add(new SetCardInfo("Zetalpa, Primal Dawn", 112, Rarity.RARE, mage.cards.z.ZetalpaPrimalDawn.class));
} }

View file

@ -991,7 +991,13 @@ public class ContinuousEffects implements Serializable {
for (ContinuousEffect effect : layer) { for (ContinuousEffect effect : layer) {
Set<Ability> abilities = layeredEffects.getAbility(effect.getId()); Set<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) { for (Ability ability : abilities) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, ability, game); effect.apply(Layer.CopyEffects_1, SubLayer.CopyEffects_1a, ability, game);
}
}
for (ContinuousEffect effect : layer) {
Set<Ability> abilities = layeredEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
effect.apply(Layer.CopyEffects_1, SubLayer.FaceDownEffects_1b, ability, game);
} }
} }
//Reload layerEffect if copy effects were applied //Reload layerEffect if copy effects were applied

View file

@ -12,7 +12,7 @@ public class CopyTokenEffect extends ContinuousEffectImpl {
protected Token token; protected Token token;
public CopyTokenEffect(Token token) { public CopyTokenEffect(Token token) {
super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature);
this.token = token.copy(); this.token = token.copy();
staticText = "You may have {this} enter the battlefield as a copy of " + token.getDescription() + " on the battlefield"; staticText = "You may have {this} enter the battlefield as a copy of " + token.getDescription() + " on the battlefield";
} }

View file

@ -71,7 +71,7 @@ public class TransformAbility extends SimpleStaticAbility {
class TransformEffect extends ContinuousEffectImpl { class TransformEffect extends ContinuousEffectImpl {
TransformEffect() { TransformEffect() {
super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.NA, Outcome.BecomeCreature); super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature);
staticText = ""; staticText = "";
} }

View file

@ -1,10 +1,11 @@
package mage.constants; package mage.constants;
/** /**
*
* @author North * @author North
*/ */
public enum SubLayer { public enum SubLayer {
CopyEffects_1a,
FaceDownEffects_1b,
CharacteristicDefining_7a, CharacteristicDefining_7a,
SetPT_7b, SetPT_7b,
ModifyPT_7c, ModifyPT_7c,

View file

@ -9,10 +9,7 @@ import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/** /**
* @author LevelX2 * @author LevelX2
@ -61,6 +58,13 @@ public class FixedTargets extends TargetPointerImpl {
this.initialized = true; this.initialized = true;
} }
public FixedTargets(Collection<MageObjectReference> morSet, Game game) {
super();
targets.addAll(morSet);
this.initialized = true;
}
private FixedTargets(final FixedTargets targetPointer) { private FixedTargets(final FixedTargets targetPointer) {
super(targetPointer); super(targetPointer);