Merge pull request #1 from magefree/master

merge
This commit is contained in:
Sarah Souders 2019-11-13 20:01:11 -05:00 committed by GitHub
commit ce3e7c1d1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 556 additions and 325 deletions

View file

@ -30,5 +30,6 @@ public class Pioneer extends Constructed {
banned.add("Felidar Guardian");
banned.add("Leyline of Abundance");
banned.add("Oath of Nissa");
banned.add("Veil of Summer");
}
}

View file

@ -0,0 +1,201 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.watchers.Watcher;
import mage.watchers.common.CastFromHandWatcher;
import java.util.UUID;
/**
* @author goesta
*/
public final class ChainerNightmareAdept extends CardImpl {
public ChainerNightmareAdept(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MINION);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Discard a card: You may cast a creature card from your graveyard this turn. Activate this ability only once each turn.
Ability ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new ChainerNightmareAdeptContinuousEffect(), new DiscardCardCost());
this.addAbility(ability, new ChainerNightmareAdeptWatcher());
// Whenever a nontoken creature enters the battlefield under your control, if you didn't cast it from your hand, it gains haste until your next turn.
this.addAbility(new ChainerNightmareAdeptTriggeredAbility(), new CastFromHandWatcher());
}
private ChainerNightmareAdept(final ChainerNightmareAdept card) {
super(card);
}
@Override
public ChainerNightmareAdept copy() {
return new ChainerNightmareAdept(this);
}
}
class ChainerNightmareAdeptContinuousEffect extends ContinuousEffectImpl {
ChainerNightmareAdeptContinuousEffect() {
super(Duration.EndOfTurn, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
staticText = "You may cast a creature card from your graveyard this turn.";
}
ChainerNightmareAdeptContinuousEffect(final ChainerNightmareAdeptContinuousEffect effect) {
super(effect);
}
@Override
public ChainerNightmareAdeptContinuousEffect copy() {
return new ChainerNightmareAdeptContinuousEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null || game.getActivePlayerId() == null || !game.isActivePlayer(player.getId())) {
return false;
}
for (Card card : player.getGraveyard().getCards(new FilterCreatureCard(), game)) {
ContinuousEffect effect = new ChainerNightmareAdeptCastFromGraveyardEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
}
return true;
}
}
class ChainerNightmareAdeptCastFromGraveyardEffect extends AsThoughEffectImpl {
ChainerNightmareAdeptCastFromGraveyardEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may cast one creature card from your graveyard";
}
ChainerNightmareAdeptCastFromGraveyardEffect(final ChainerNightmareAdeptCastFromGraveyardEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public ChainerNightmareAdeptCastFromGraveyardEffect copy() {
return new ChainerNightmareAdeptCastFromGraveyardEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(objectId);
if (card != null
&& card.getId().equals(getTargetPointer().getFirst(game, source))
&& card.isCreature()
&& card.getSpellAbility() != null
&& affectedControllerId != null
&& card.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)
&& affectedControllerId.equals(source.getControllerId())) {
ChainerNightmareAdeptWatcher watcher = game.getState().getWatcher(ChainerNightmareAdeptWatcher.class, source.getSourceId());
return watcher != null && !watcher.isAbilityUsed();
}
return false;
}
}
class ChainerNightmareAdeptWatcher extends Watcher {
private boolean abilityUsed = false;
ChainerNightmareAdeptWatcher() {
super(WatcherScope.CARD);
}
ChainerNightmareAdeptWatcher(final ChainerNightmareAdeptWatcher watcher) {
super(watcher);
this.abilityUsed = watcher.abilityUsed;
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.SPELL_CAST && event.getZone() == Zone.GRAVEYARD) {
Spell spell = (Spell) game.getObject(event.getTargetId());
if (spell.isCreature()) {
abilityUsed = true;
}
}
}
@Override
public ChainerNightmareAdeptWatcher copy() {
return new ChainerNightmareAdeptWatcher(this);
}
@Override
public void reset() {
super.reset();
abilityUsed = false;
}
public boolean isAbilityUsed() {
return abilityUsed;
}
}
class ChainerNightmareAdeptTriggeredAbility extends EntersBattlefieldAllTriggeredAbility {
private final static String abilityText = "Whenever a nontoken creature enters the battlefield under your control, " +
"if you didn't cast it from your hand, it gains haste until your next turn.";
private final static ContinuousEffect gainHasteUntilNextTurnEffect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.UntilYourNextTurn);
private final static FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another nontoken creature");
static {
filter.add(Predicates.not(TokenPredicate.instance));
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(AnotherPredicate.instance);
}
public ChainerNightmareAdeptTriggeredAbility() {
super(Zone.BATTLEFIELD, gainHasteUntilNextTurnEffect, filter, false, SetTargetPointer.PERMANENT, abilityText);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!super.checkTrigger(event, game)) {
return false;
}
CastFromHandWatcher watcher = game.getState().getWatcher(CastFromHandWatcher.class);
return watcher != null && !watcher.spellWasCastFromHand(event.getSourceId());
}
}

View file

@ -3,6 +3,7 @@ package mage.cards.d;
import java.util.UUID;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
@ -26,7 +27,9 @@ public final class DeadlyAllure extends CardImpl {
// Target creature gains deathtouch until end of turn and must be blocked this turn if able.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
effect.setText("and must be blocked this turn if able");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Flashback {G}

View file

@ -27,11 +27,11 @@ public final class ElementalUprising extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}");
// Target land you control becomes a 4/4 Elemental creature with haste until end of turn. It's still a land. It must be blocked this turn if able.
getSpellAbility().addEffect(new BecomesCreatureTargetEffect(new ElementalUprisingToken(), false, true, Duration.EndOfTurn));
getSpellAbility().addTarget(new TargetPermanent(new FilterControlledLandPermanent()));
this.getSpellAbility().addEffect(new BecomesCreatureTargetEffect(new ElementalUprisingToken(), false, true, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetPermanent(new FilterControlledLandPermanent()));
Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
effect.setText("It must be blocked this turn if able");
getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(effect);
}
public ElementalUprising(final ElementalUprising card) {

View file

@ -23,7 +23,7 @@ public final class EmergentGrowth extends CardImpl {
// Target creature gets +5/+5 until end of turn and must be blocked this turn if able.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new BoostTargetEffect(5, 5, Duration.EndOfTurn));
Effect effect = new MustBeBlockedByAtLeastOneTargetEffect();
Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
effect.setText("and must be blocked this turn if able");
this.getSpellAbility().addEffect(effect);
}

View file

@ -2,6 +2,7 @@
package mage.cards.e;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
@ -25,7 +26,9 @@ public final class Enlarge extends CardImpl {
// Target creature gets +7/+7 and gains trample until end of turn. It must be blocked this turn if able.
this.getSpellAbility().addEffect(new BoostTargetEffect(7,7, Duration.EndOfTurn));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
Effect effect = new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn);
effect.setText("It must be blocked this turn if able");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}

View file

@ -5,6 +5,7 @@ import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneSourceEffect;
import mage.abilities.effects.Effect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;

View file

@ -2,15 +2,12 @@
package mage.cards.i;
import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByAtLeastOneTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
/**
@ -25,10 +22,7 @@ public final class IrresistiblePrey extends CardImpl {
// Target creature must be blocked this turn if able.
// Draw a card.
this.getSpellAbility().addEffect(
new GainAbilityTargetEffect(
new SimpleStaticAbility(Zone.BATTLEFIELD, new MustBeBlockedByAtLeastOneTargetEffect()),
Duration.EndOfTurn));
this.getSpellAbility().addEffect(new MustBeBlockedByAtLeastOneTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
}

View file

@ -54,6 +54,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Burning Vengeance", 135, Rarity.UNCOMMON, mage.cards.b.BurningVengeance.class));
cards.add(new SetCardInfo("Burnished Hart", 211, Rarity.UNCOMMON, mage.cards.b.BurnishedHart.class));
cards.add(new SetCardInfo("Call to the Netherworld", 108, Rarity.COMMON, mage.cards.c.CallToTheNetherworld.class));
cards.add(new SetCardInfo("Chainer, Nightmare Adept", 39, Rarity.MYTHIC, mage.cards.c.ChainerNightmareAdept.class));
cards.add(new SetCardInfo("Champion of Stray Souls", 109, Rarity.MYTHIC, mage.cards.c.ChampionOfStraySouls.class));
cards.add(new SetCardInfo("Chaos Warp", 136, Rarity.RARE, mage.cards.c.ChaosWarp.class));
cards.add(new SetCardInfo("Chemister's Insight", 80, Rarity.UNCOMMON, mage.cards.c.ChemistersInsight.class));

View file

@ -542,4 +542,31 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
}
@Test
public void irresistiblePreyMustBeBlockedTest() {
addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Irresistible Prey");
addCard(Zone.BATTLEFIELD, playerB, "Bronze Sable");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Irresistible Prey", "Llanowar Elves"); // must be blocked
attack(1, playerA, "Llanowar Elves");
attack(1, playerA, "Alpha Myr");
// attempt to block the creature that doesn't have "must be blocked"
block(1, playerB, "Bronze Sable", "Alpha Myr");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerA, "Irresistible Prey", 1);
assertGraveyardCount(playerA, "Llanowar Elves", 1);
assertGraveyardCount(playerB, "Bronze Sable", 1);
assertTapped("Alpha Myr", true);
assertLife(playerB, 18);
}
}