mirror of
https://github.com/magefree/mage.git
synced 2025-12-28 14:32:06 -08:00
* Dash - Fixed that the creature was returned to hand from dash also if it left battlefield before.
This commit is contained in:
parent
9be613beb9
commit
c942592c3b
5 changed files with 112 additions and 34 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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 spell’s dash cost was paid, return the
|
||||
* permanent this spell becomes to its owner’s hand at the beginning of the next end step,” and “As
|
||||
* long as this permanent’s dash cost was paid, it has haste.” Paying a card’s dash cost follows the
|
||||
* rules for paying alternative costs in rules 601.2b and 601.2e–g.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 spell’s dash cost was paid, return the permanent this
|
||||
* spell becomes to its owner’s hand at the beginning of the next end step,”
|
||||
* and “As long as this permanent’s dash cost was paid, it has haste.”
|
||||
* Paying a card’s dash cost follows the rules for paying alternative costs
|
||||
* in rules 601.2b and 601.2e–g.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue