[NEO] Implemented Behold the Unspeakable / Vision of the Unspeakable

This commit is contained in:
Evan Kranzler 2022-02-02 19:41:47 -05:00
parent fe857f8db6
commit ba05bc13c4
5 changed files with 157 additions and 22 deletions

View file

@ -0,0 +1,63 @@
package mage.cards.b;
import mage.abilities.common.SagaAbility;
import mage.abilities.condition.common.HeckbentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class BeholdTheUnspeakable extends CardImpl {
public BeholdTheUnspeakable(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}");
this.subtype.add(SubType.SAGA);
this.secondSideCardClazz = mage.cards.v.VisionOfTheUnspeakable.class;
// (As this Saga enters and after your draw step, add a lore counter.)
SagaAbility sagaAbility = new SagaAbility(this);
// I Creatures you don't control get -2/-0 until your next turn.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new BoostAllEffect(
-2, 0, Duration.UntilYourNextTurn,
StaticFilters.FILTER_CREATURES_YOU_DONT_CONTROL, false
));
// II If you have one or fewer cards in hand, draw four cards. Otherwise, scry 2, then draw two cards.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(4), new ScryEffect(2),
HeckbentCondition.instance, "if you have one or fewer cards in hand, " +
"draw four cards. Otherwise, scry 2, then draw two cards"
).addOtherwiseEffect(new DrawCardSourceControllerEffect(2)));
// III Exile this Saga, then return it to the battlefield transformed under your control.
this.addAbility(new TransformAbility());
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect());
this.addAbility(sagaAbility);
}
private BeholdTheUnspeakable(final BeholdTheUnspeakable card) {
super(card);
}
@Override
public BeholdTheUnspeakable copy() {
return new BeholdTheUnspeakable(this);
}
}

View file

@ -0,0 +1,53 @@
package mage.cards.v;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.CardsInControllerHandCount;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class VisionOfTheUnspeakable extends CardImpl {
public VisionOfTheUnspeakable(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(0);
this.toughness = new MageInt(0);
this.color.setBlue(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Vision of the Unspeakable gets +1/+1 for each card in your hand.
this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(
CardsInControllerHandCount.instance,
CardsInControllerHandCount.instance,
Duration.WhileOnBattlefield
)));
}
private VisionOfTheUnspeakable(final VisionOfTheUnspeakable card) {
super(card);
}
@Override
public VisionOfTheUnspeakable copy() {
return new VisionOfTheUnspeakable(this);
}
}

View file

@ -40,6 +40,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
cards.add(new SetCardInfo("Bamboo Grove Archer", 173, Rarity.COMMON, mage.cards.b.BambooGroveArcher.class));
cards.add(new SetCardInfo("Banishing Slash", 3, Rarity.UNCOMMON, mage.cards.b.BanishingSlash.class));
cards.add(new SetCardInfo("Befriending the Moths", 4, Rarity.COMMON, mage.cards.b.BefriendingTheMoths.class));
cards.add(new SetCardInfo("Behold the Unspeakable", 48, Rarity.UNCOMMON, mage.cards.b.BeholdTheUnspeakable.class));
cards.add(new SetCardInfo("Biting-Palm Ninja", 88, Rarity.RARE, mage.cards.b.BitingPalmNinja.class));
cards.add(new SetCardInfo("Boseiju Reaches Skyward", 177, Rarity.UNCOMMON, mage.cards.b.BoseijuReachesSkyward.class));
cards.add(new SetCardInfo("Branch of Boseiju", 177, Rarity.UNCOMMON, mage.cards.b.BranchOfBoseiju.class));
@ -128,6 +129,7 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
cards.add(new SetCardInfo("Unstoppable Ogre", 169, Rarity.COMMON, mage.cards.u.UnstoppableOgre.class));
cards.add(new SetCardInfo("Upriser Renegade", 170, Rarity.UNCOMMON, mage.cards.u.UpriserRenegade.class));
cards.add(new SetCardInfo("Vector Glider", 66, Rarity.COMMON, mage.cards.v.VectorGlider.class));
cards.add(new SetCardInfo("Vision of the Unspeakable", 48, Rarity.UNCOMMON, mage.cards.v.VisionOfTheUnspeakable.class));
cards.add(new SetCardInfo("You Are Already Dead", 129, Rarity.COMMON, mage.cards.y.YouAreAlreadyDead.class));
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); // remove when mechanic is fully implemented

View file

@ -1,10 +1,9 @@
package mage.abilities.decorator;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.condition.Condition;
import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect;
import mage.game.Game;
@ -15,9 +14,9 @@ import mage.game.Game;
*/
public class ConditionalOneShotEffect extends OneShotEffect {
private OneShotEffect effect;
private OneShotEffect otherwiseEffect;
private Condition condition;
private final Effects effects = new Effects();
private final Effects otherwiseEffects = new Effects();
private final Condition condition;
public ConditionalOneShotEffect(OneShotEffect effect, Condition condition) {
this(effect, null, condition, null);
@ -29,31 +28,43 @@ public class ConditionalOneShotEffect extends OneShotEffect {
public ConditionalOneShotEffect(OneShotEffect effect, OneShotEffect otherwiseEffect, Condition condition, String text) {
super(effect.getOutcome());
this.effect = effect;
this.otherwiseEffect = otherwiseEffect;
if (effect != null) {
this.effects.add(effect);
}
if (otherwiseEffect != null) {
this.otherwiseEffects.add(otherwiseEffect);
}
this.condition = condition;
this.staticText = text;
}
public ConditionalOneShotEffect(ConditionalOneShotEffect effect) {
super(effect);
this.effect = (OneShotEffect) effect.effect.copy();
if (effect.otherwiseEffect != null) {
this.otherwiseEffect = (OneShotEffect) effect.otherwiseEffect.copy();
}
this.effects.addAll(effect.effects.copy());
this.otherwiseEffects.addAll(effect.otherwiseEffects.copy());
this.condition = effect.condition;
}
@Override
public boolean apply(Game game, Ability source) {
if (condition.apply(game, source)) {
effect.setTargetPointer(this.targetPointer);
return effect.apply(game, source);
} else if (otherwiseEffect == null) {
return true; // nothing to do - no problem
// nothing to do - no problem
Effects toApply = condition.apply(game, source) ? effects : otherwiseEffects;
if (toApply.isEmpty()) {
return false;
}
otherwiseEffect.setTargetPointer(this.targetPointer);
return otherwiseEffect.apply(game, source);
toApply.setTargetPointer(this.targetPointer);
toApply.stream().forEach(effect -> effect.apply(game, source));
return true;
}
public ConditionalOneShotEffect addEffect(OneShotEffect effect) {
this.effects.add(effect);
return this;
}
public ConditionalOneShotEffect addOtherwiseEffect(OneShotEffect effect) {
this.effects.add(effect);
return this;
}
@Override
@ -66,10 +77,9 @@ public class ConditionalOneShotEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
if (otherwiseEffect == null) {
return "if " + condition.toString() + ", " + effect.getText(mode);
if (otherwiseEffects.isEmpty()) {
return "if " + condition.toString() + ", " + effects.getText(mode);
}
return effect.getText(mode) + ". If " + condition.toString() + ", " + otherwiseEffect.getText(mode);
return effects.getText(mode) + ". If " + condition.toString() + ", " + otherwiseEffects.getText(mode);
}
}

View file

@ -455,6 +455,13 @@ public final class StaticFilters {
FILTER_CREATURE_YOU_DONT_CONTROL.setLockedFilter(true);
}
public static final FilterCreaturePermanent FILTER_CREATURES_YOU_DONT_CONTROL = new FilterCreaturePermanent("creatures you don't control");
static {
FILTER_CREATURES_YOU_DONT_CONTROL.add(TargetController.NOT_YOU.getControllerPredicate());
FILTER_CREATURES_YOU_DONT_CONTROL.setLockedFilter(true);
}
public static final FilterControlledCreaturePermanent FILTER_CONTROLLED_CREATURE = new FilterControlledCreaturePermanent();
static {