* Dash - Fixed that the creature was returned to hand from dash also if it left battlefield before.

This commit is contained in:
LevelX2 2015-07-06 13:36:23 +02:00
parent 9be613beb9
commit c942592c3b
5 changed files with 112 additions and 34 deletions

View file

@ -67,7 +67,6 @@ public class AngelOfSerenity extends CardImpl {
this.power = new MageInt(5);
this.toughness = new MageInt(6);
// Flying
this.addAbility(FlyingAbility.getInstance());
@ -75,7 +74,7 @@ public class AngelOfSerenity extends CardImpl {
this.addAbility(new AngelOfSerenityTriggeredAbility());
// When Angel of Serenity leaves the battlefield, return the exiled cards to their owners' hands.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new AngelOfSerenityLeaveEffect(), false ));
this.addAbility(new LeavesBattlefieldTriggeredAbility(new AngelOfSerenityLeaveEffect(), false));
}
public AngelOfSerenity(final AngelOfSerenity card) {
@ -104,7 +103,7 @@ class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility {
getTargets().clear();
FilterCreaturePermanent filter = new FilterCreaturePermanent("up to three other target creatures");
filter.add(new AnotherPredicate());
TargetCreaturePermanent target1 = new TargetCreaturePermanent(0,3, filter, false);
TargetCreaturePermanent target1 = new TargetCreaturePermanent(0, 3, filter, false);
game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target1, this, game);
if (target1.getTargets().size() > 0) {
getTargets().add(target1);
@ -112,8 +111,8 @@ class AngelOfSerenityTriggeredAbility extends ZoneChangeTriggeredAbility {
}
int leftTargets = 3 - target1.getTargets().size();
if (leftTargets > 0) {
FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1?"s":"") +" from graveyards");
TargetCardInGraveyard target2 = new TargetCardInGraveyard(0,leftTargets, filter2);
FilterCard filter2 = new FilterCreatureCard("up to " + leftTargets + " target creature card" + (leftTargets > 1 ? "s" : "") + " from graveyards");
TargetCardInGraveyard target2 = new TargetCardInGraveyard(0, leftTargets, filter2);
game.getPlayer(getControllerId()).chooseTarget(Outcome.Exile, target2, this, game);
if (target2.getTargets().size() > 0) {
getTargets().add(target2);
@ -160,7 +159,7 @@ class AngelOfSerenityEnterEffect extends OneShotEffect {
}
}
} else if (target instanceof TargetCardInGraveyard){
} else if (target instanceof TargetCardInGraveyard) {
for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {

View file

@ -34,7 +34,6 @@ import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.MonocoloredPredicate;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
/**
@ -53,7 +52,6 @@ public class UltimatePrice extends CardImpl {
super(ownerId, 82, "Ultimate Price", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{B}");
this.expansionSetCode = "RTR";
// Destroy target monocolored creature.
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
this.getSpellAbility().addEffect(new DestroyTargetEffect());

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep;
@ -40,26 +39,25 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class DashTest extends CardTestPlayerBase {
/**
* 702.108. Dash
* 702.108a Dash represents three abilities: two static abilities that function while the card with dash is
* on the stack, one of which may create a delayed triggered ability, and a static ability that
* functions while the object with dash is on the battlefield. Dash [cost] means You may cast
* this card by paying [cost] rather that its mana cost, If this spells dash cost was paid, return the
* permanent this spell becomes to its owners hand at the beginning of the next end step, and As
* long as this permanents dash cost was paid, it has haste. Paying a cards dash cost follows the
* rules for paying alternative costs in rules 601.2b and 601.2eg.
*
*/
/**
* Screamreach Brawler
* Creature Orc Berserker 2/3, 2R (3)
* Dash {1}{R} (You may cast this spell for its dash cost. If you do, it
* gains haste, and it's returned from the battlefield to its owner's hand
* at the beginning of the next end step.)
* 702.108. Dash 702.108a Dash represents three abilities: two static
* abilities that function while the card with dash is on the stack, one of
* which may create a delayed triggered ability, and a static ability that
* functions while the object with dash is on the battlefield. Dash [cost]
* means You may cast this card by paying [cost] rather that its mana
* cost, If this spells dash cost was paid, return the permanent this
* spell becomes to its owners hand at the beginning of the next end step,
* and As long as this permanents dash cost was paid, it has haste.
* Paying a cards dash cost follows the rules for paying alternative costs
* in rules 601.2b and 601.2eg.
*
*/
/**
* Screamreach Brawler Creature Orc Berserker 2/3, 2R (3) Dash {1}{R} (You
* may cast this spell for its dash cost. If you do, it gains haste, and
* it's returned from the battlefield to its owner's hand at the beginning
* of the next end step.)
*
*/
@Test
public void testDash() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
@ -96,4 +94,30 @@ public class DashTest extends CardTestPlayerBase {
}
/**
* Also dash returns creatures to your hand at end of turn even if they died
* that turn.
*/
@Test
public void testDashedCreatureDiesInCombat() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.HAND, playerA, "Screamreach Brawler"); // 2/3
addCard(Zone.BATTLEFIELD, playerB, "Geist of the Moors", 1); // 3/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Screamreach Brawler");
setChoice(playerA, "Yes");
attack(1, playerA, "Screamreach Brawler");
block(1, playerB, "Geist of the Moors", "Screamreach Brawler");
setStopAt(2, PhaseStep.UNTAP);
execute();
assertLife(playerB, 20);
assertPermanentCount(playerA, "Screamreach Brawler", 0);
assertHandCount(playerA, "Screamreach Brawler", 0);
assertGraveyardCount(playerA, "Screamreach Brawler", 1);
assertGraveyardCount(playerB, "Geist of the Moors", 1);
}
}

View file

@ -211,4 +211,31 @@ public class RenownTest extends CardTestPlayerBase {
}
/**
* Ability doesn't trigger when renowned. ("Whenever an opponent casts a
* noncreature spell, if ~ is renowned, ~ deals 2 damage to that player.")
*/
@Test
public void testScabClanBerserker() {
// Renown 1
// Whenever an opponent casts a noncreature spell, if Scab-Clan Berserker is renowned, Scab-Clan Berserker deals 2 damage to that player.
addCard(Zone.BATTLEFIELD, playerA, "Scab-Clan Berserker"); // 2/2 {1}{R}{R}
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Lightning Bolt");
attack(3, playerA, "Scab-Clan Berserker"); // 1 damage
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
setStopAt(3, PhaseStep.END_TURN);
execute();
Permanent berserker = getPermanent("Scab-Clan Berserker", playerA);
Assert.assertEquals("has has renown", true, berserker.isRenown());
assertPowerToughness(playerA, "Scab-Clan Berserker", 3, 3);
assertLife(playerA, 17); // Lightning Bolt
assertLife(playerB, 16); // 2 from attack 2 from triggered ability
}
}

View file

@ -31,6 +31,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.SpellAbility;
import mage.abilities.StaticAbility;
import mage.abilities.common.EntersBattlefieldAbility;
@ -44,7 +45,7 @@ import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.cards.Card;
@ -76,12 +77,9 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts
Ability ability = new EntersBattlefieldAbility(
new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom, false),
DashedCondition.getInstance(), false, "", "");
Effect effect = new ReturnToHandTargetEffect();
effect.setText("return the dashed creature from the battlefield to its owner's hand");
effect.setTargetPointer(new FixedTarget(card.getId()));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), false));
ability.addEffect(new DashAddDelayedTriggeredAbilityEffect());
addSubAbility(ability);
}
public DashAbility(final DashAbility ability) {
@ -134,7 +132,7 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts
this.resetDash();
for (AlternativeCost2 dashCost : alternativeSourceCosts) {
if (dashCost.canPay(ability, sourceId, controllerId, game)
&& player.chooseUse(Outcome.Benefit, new StringBuilder(KEYWORD).append(" the creature for ").append(dashCost.getText(true)).append(" ?").toString(), ability, game)) {
&& player.chooseUse(Outcome.Benefit, KEYWORD + " the creature for " + dashCost.getText(true) + " ?", ability, game)) {
activateDash(dashCost, game);
ability.getManaCostsToPay().clear();
ability.getCosts().clear();
@ -209,3 +207,35 @@ public class DashAbility extends StaticAbility implements AlternativeSourceCosts
return alterCosts;
}
}
class DashAddDelayedTriggeredAbilityEffect extends OneShotEffect {
public DashAddDelayedTriggeredAbilityEffect() {
super(Outcome.Benefit);
this.staticText = "return the dashed creature from the battlefield to its owner's hand";
}
public DashAddDelayedTriggeredAbilityEffect(final DashAddDelayedTriggeredAbilityEffect effect) {
super(effect);
}
@Override
public DashAddDelayedTriggeredAbilityEffect copy() {
return new DashAddDelayedTriggeredAbilityEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Effect effect = new ReturnToHandTargetEffect();
effect.setText("return the dashed creature from the battlefield to its owner's hand");
effect.setTargetPointer(new FixedTarget(source.getSourceId()));
// init target pointer now because the dashed creature will only be returned from current zone
effect.getTargetPointer().init(game, source);
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
delayedAbility.setSourceObject(source.getSourceObject(game), game);
game.addDelayedTriggeredAbility(delayedAbility);
return false;
}
}