mirror of
https://github.com/correl/mage.git
synced 2024-12-01 11:09:56 +00:00
[BOK] reworked implementation of Shirei, Shizo's Caretaker and added test
This commit is contained in:
parent
2a00609918
commit
3cbfe4d623
13 changed files with 140 additions and 176 deletions
|
@ -69,7 +69,7 @@ class LifelineEffect extends OneShotEffect {
|
||||||
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
|
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false);
|
||||||
effect.setTargetPointer(new FixedTarget(card, game));
|
effect.setTargetPointer(new FixedTarget(card, game));
|
||||||
effect.setText("return that card to the battlefield under it's owner's control at the beginning of the next end step");
|
effect.setText("return that card to the battlefield under it's owner's control at the beginning of the next end step");
|
||||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.ANY), source);
|
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, TargetController.ANY), source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -118,7 +118,7 @@ class MaddeningImpCreateDelayedTriggeredAbilityEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
|
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
|
||||||
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.ALL, new MaddeningImpDelayedDestroyEffect(activeCreatures), TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance));
|
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new MaddeningImpDelayedDestroyEffect(activeCreatures), TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance));
|
||||||
delayedAbility.getDuration();
|
delayedAbility.getDuration();
|
||||||
game.addDelayedTriggeredAbility(delayedAbility, source);
|
game.addDelayedTriggeredAbility(delayedAbility, source);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -103,7 +103,7 @@ class NettlingImpDelayedDestroyEffect extends OneShotEffect {
|
||||||
DestroyTargetEffect effect = new DestroyTargetEffect();
|
DestroyTargetEffect effect = new DestroyTargetEffect();
|
||||||
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
|
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
|
||||||
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
|
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
|
||||||
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.ALL, effect, TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance));
|
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance));
|
||||||
delayedAbility.getDuration();
|
delayedAbility.getDuration();
|
||||||
delayedAbility.getTargets().addAll(source.getTargets());
|
delayedAbility.getTargets().addAll(source.getTargets());
|
||||||
game.addDelayedTriggeredAbility(delayedAbility, source);
|
game.addDelayedTriggeredAbility(delayedAbility, source);
|
||||||
|
|
|
@ -104,7 +104,7 @@ class NorrittDelayedDestroyEffect extends OneShotEffect {
|
||||||
DestroyTargetEffect effect = new DestroyTargetEffect();
|
DestroyTargetEffect effect = new DestroyTargetEffect();
|
||||||
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
|
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
|
||||||
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
|
AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility
|
||||||
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.ALL, effect, TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance));
|
= new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance));
|
||||||
delayedAbility.getDuration();
|
delayedAbility.getDuration();
|
||||||
delayedAbility.getTargets().addAll(source.getTargets());
|
delayedAbility.getTargets().addAll(source.getTargets());
|
||||||
game.addDelayedTriggeredAbility(delayedAbility, source);
|
game.addDelayedTriggeredAbility(delayedAbility, source);
|
||||||
|
|
|
@ -55,7 +55,7 @@ public final class SeeRed extends CardImpl {
|
||||||
|
|
||||||
// At the beginning of your end step, if you didn't attack with a creature this turn, sacrifice See Red.
|
// At the beginning of your end step, if you didn't attack with a creature this turn, sacrifice See Red.
|
||||||
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||||
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceEffect(), TargetController.YOU),
|
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect(), TargetController.YOU),
|
||||||
new InvertCondition(ControllerAttackedThisTurnCondition.instance),
|
new InvertCondition(ControllerAttackedThisTurnCondition.instance),
|
||||||
"At the beginning of your end step, if you didn't attack with a creature this turn, sacrifice {this}."), new AttackedThisTurnWatcher());
|
"At the beginning of your end step, if you didn't attack with a creature this turn, sacrifice {this}."), new AttackedThisTurnWatcher());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,38 @@
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import mage.MageInt;
|
import mage.MageInt;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.common.DiesCreatureTriggeredAbility;
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
|
||||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.condition.common.SourceOnBattlefieldCondition;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.decorator.ConditionalOneShotEffect;
|
||||||
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect;
|
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||||
import mage.cards.Card;
|
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.filter.FilterPermanent;
|
||||||
import mage.game.events.GameEvent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.game.events.ZoneChangeEvent;
|
import mage.filter.predicate.mageobject.PowerPredicate;
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.target.targetpointer.FixedTarget;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author emerald000
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
public final class ShireiShizosCaretaker extends CardImpl {
|
public final class ShireiShizosCaretaker extends CardImpl {
|
||||||
|
|
||||||
|
private static final FilterPermanent filter = new FilterCreaturePermanent();
|
||||||
|
|
||||||
|
static {
|
||||||
|
filter.add(TargetController.YOU.getOwnerPredicate());
|
||||||
|
filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String rule1 = "you may return that card to the battlefield " +
|
||||||
|
"t the beginning of the next end step if {this} is still on the battlefield";
|
||||||
|
private static final String rule2 = "Whenever a creature with power 1 or less " +
|
||||||
|
"is put into your graveyard from the battlefield, ";
|
||||||
|
|
||||||
public ShireiShizosCaretaker(UUID ownerId, CardSetInfo setInfo) {
|
public ShireiShizosCaretaker(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
|
||||||
addSuperType(SuperType.LEGENDARY);
|
addSuperType(SuperType.LEGENDARY);
|
||||||
|
@ -34,7 +42,12 @@ public final class ShireiShizosCaretaker extends CardImpl {
|
||||||
this.toughness = new MageInt(2);
|
this.toughness = new MageInt(2);
|
||||||
|
|
||||||
// Whenever a creature with power 1 or less is put into your graveyard from the battlefield, you may return that card to the battlefield at the beginning of the next end step if Shirei, Shizo's Caretaker is still on the battlefield.
|
// Whenever a creature with power 1 or less is put into your graveyard from the battlefield, you may return that card to the battlefield at the beginning of the next end step if Shirei, Shizo's Caretaker is still on the battlefield.
|
||||||
this.addAbility(new ShireiShizosCaretakerTriggeredAbility(this.getId()));
|
this.addAbility(new DiesCreatureTriggeredAbility(new CreateDelayedTriggeredAbilityEffect(
|
||||||
|
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new ConditionalOneShotEffect(
|
||||||
|
new ReturnFromGraveyardToBattlefieldTargetEffect(), SourceOnBattlefieldCondition.instance,
|
||||||
|
"you may return that card to the battlefield if {this} is still on the battlefield"
|
||||||
|
), TargetController.ANY, null, true)
|
||||||
|
).setText(rule1), false, filter, true).setTriggerPhrase(rule2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ShireiShizosCaretaker(final ShireiShizosCaretaker card) {
|
private ShireiShizosCaretaker(final ShireiShizosCaretaker card) {
|
||||||
|
@ -46,110 +59,3 @@ public final class ShireiShizosCaretaker extends CardImpl {
|
||||||
return new ShireiShizosCaretaker(this);
|
return new ShireiShizosCaretaker(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShireiShizosCaretakerTriggeredAbility extends TriggeredAbilityImpl {
|
|
||||||
|
|
||||||
ShireiShizosCaretakerTriggeredAbility(UUID shireiId) {
|
|
||||||
super(Zone.BATTLEFIELD, new ShireiShizosCaretakerEffect(shireiId), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShireiShizosCaretakerTriggeredAbility(final ShireiShizosCaretakerTriggeredAbility ability) {
|
|
||||||
super(ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ShireiShizosCaretakerTriggeredAbility copy() {
|
|
||||||
return new ShireiShizosCaretakerTriggeredAbility(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkEventType(GameEvent event, Game game) {
|
|
||||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
|
||||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
|
||||||
Permanent LKIpermanent = game.getPermanentOrLKIBattlefield(zEvent.getTargetId());
|
|
||||||
Card card = game.getCard(zEvent.getTargetId());
|
|
||||||
if (card != null
|
|
||||||
&& LKIpermanent != null
|
|
||||||
&& card.isOwnedBy(this.controllerId)
|
|
||||||
&& zEvent.isDiesEvent()
|
|
||||||
&& card.isCreature(game)
|
|
||||||
&& LKIpermanent.getPower().getValue() <= 1) {
|
|
||||||
for (Effect effect : this.getEffects()) {
|
|
||||||
effect.setTargetPointer(new FixedTarget(zEvent.getTargetId()));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRule() {
|
|
||||||
return "Whenever a creature with power 1 or less is put into your graveyard from the battlefield, you may return that card to the battlefield at the beginning of the next end step if Shirei, Shizo's Caretaker is still on the battlefield.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ShireiShizosCaretakerEffect extends OneShotEffect {
|
|
||||||
|
|
||||||
protected final UUID shireiId;
|
|
||||||
|
|
||||||
ShireiShizosCaretakerEffect(UUID shireiId) {
|
|
||||||
super(Outcome.PutCreatureInPlay);
|
|
||||||
this.staticText = "you may return that card to the battlefield at the beginning of the next end step if {this} is still on the battlefield.";
|
|
||||||
this.shireiId = shireiId;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShireiShizosCaretakerEffect(final ShireiShizosCaretakerEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
this.shireiId = effect.shireiId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ShireiShizosCaretakerEffect copy() {
|
|
||||||
return new ShireiShizosCaretakerEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
|
|
||||||
if (card != null) {
|
|
||||||
Effect effect = new ShireiShizosCaretakerReturnEffect(shireiId);
|
|
||||||
effect.setText("return that card to the battlefield if {this} is still on the battlefield");
|
|
||||||
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
|
|
||||||
delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(card, game));
|
|
||||||
game.addDelayedTriggeredAbility(delayedAbility, source);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ShireiShizosCaretakerReturnEffect extends ReturnToBattlefieldUnderYourControlTargetEffect {
|
|
||||||
|
|
||||||
protected final UUID shireiId;
|
|
||||||
|
|
||||||
ShireiShizosCaretakerReturnEffect(UUID shireiId) {
|
|
||||||
this.shireiId = shireiId;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShireiShizosCaretakerReturnEffect(final ShireiShizosCaretakerReturnEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
this.shireiId = effect.shireiId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ShireiShizosCaretakerReturnEffect copy() {
|
|
||||||
return new ShireiShizosCaretakerReturnEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
if (game.getBattlefield().containsPermanent(shireiId)) {
|
|
||||||
return super.apply(game, source);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ class TilonallisSummonerEffect extends OneShotEffect {
|
||||||
.setText("exile those tokens unless you have the city's blessing");
|
.setText("exile those tokens unless you have the city's blessing");
|
||||||
exileEffect.setTargetPointer(new FixedTargets(new CardsImpl(effect.getLastAddedTokenIds()), game));
|
exileEffect.setTargetPointer(new FixedTargets(new CardsImpl(effect.getLastAddedTokenIds()), game));
|
||||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
|
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
|
||||||
Zone.ALL, exileEffect, TargetController.ANY, new InvertCondition(CitysBlessingCondition.instance)), source);
|
exileEffect, TargetController.ANY, new InvertCondition(CitysBlessingCondition.instance)), source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package org.mage.test.cards.single.bok;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public class ShireiShizosCaretakerTest extends CardTestPlayerBase {
|
||||||
|
private static final String shirei = "Shirei, Shizo's Caretaker";
|
||||||
|
private static final String rats = "Muck Rats";
|
||||||
|
private static final String murder = "Murder";
|
||||||
|
private static final String blink = "Momentary Blink";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegular() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, shirei);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, rats);
|
||||||
|
addCard(Zone.HAND, playerA, murder);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, murder, rats);
|
||||||
|
setChoice(playerA, true);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
assertPermanentCount(playerA, shirei, 1);
|
||||||
|
assertPermanentCount(playerA, rats, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLeftBattlefield() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, shirei);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, rats);
|
||||||
|
addCard(Zone.HAND, playerA, murder, 2);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, murder, rats);
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, shirei);
|
||||||
|
setChoice(playerA, true);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
assertPermanentCount(playerA, shirei, 0);
|
||||||
|
assertPermanentCount(playerA, rats, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBlinked() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Scrubland", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, shirei);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, rats);
|
||||||
|
addCard(Zone.HAND, playerA, murder);
|
||||||
|
addCard(Zone.HAND, playerA, blink);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, murder, rats);
|
||||||
|
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, blink, shirei);
|
||||||
|
setChoice(playerA, true);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
assertPermanentCount(playerA, shirei, 1);
|
||||||
|
assertPermanentCount(playerA, rats, 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.abilities.common.delayed;
|
package mage.abilities.common.delayed;
|
||||||
|
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
|
@ -6,34 +5,32 @@ import mage.abilities.condition.Condition;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.constants.Duration;
|
import mage.constants.Duration;
|
||||||
import mage.constants.TargetController;
|
import mage.constants.TargetController;
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author North
|
* @author North
|
||||||
*/
|
*/
|
||||||
public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||||
|
|
||||||
private TargetController targetController;
|
private final TargetController targetController;
|
||||||
private Condition condition;
|
private final Condition condition;
|
||||||
|
|
||||||
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Effect effect) {
|
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Effect effect) {
|
||||||
this(effect, TargetController.ANY);
|
this(effect, TargetController.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Effect effect, TargetController targetController) {
|
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Effect effect, TargetController targetController) {
|
||||||
this(Zone.ALL, effect, targetController);
|
this(effect, targetController, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone zone, Effect effect, TargetController targetController) {
|
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Effect effect, TargetController targetController, Condition condition) {
|
||||||
this(zone, effect, targetController, null);
|
this(effect, targetController, condition, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone zone, Effect effect, TargetController targetController, Condition condition) {
|
public AtTheBeginOfNextEndStepDelayedTriggeredAbility(Effect effect, TargetController targetController, Condition condition, boolean optional) {
|
||||||
super(effect, Duration.Custom);
|
super(effect, Duration.Custom, true, optional);
|
||||||
this.zone = zone;
|
this.zone = zone;
|
||||||
this.targetController = targetController;
|
this.targetController = targetController;
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
|
@ -52,32 +49,33 @@ public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTrigg
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkTrigger(GameEvent event, Game game) {
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
boolean correctEndPhase = false;
|
|
||||||
switch (targetController) {
|
switch (targetController) {
|
||||||
case ANY:
|
case ANY:
|
||||||
correctEndPhase = true;
|
|
||||||
break;
|
break;
|
||||||
case YOU:
|
case YOU:
|
||||||
correctEndPhase = event.getPlayerId().equals(this.controllerId);
|
if (!isControlledBy(event.getPlayerId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OPPONENT:
|
case OPPONENT:
|
||||||
if (game.getPlayer(this.getControllerId()).hasOpponent(event.getPlayerId(), game)) {
|
if (!game.getOpponents(this.getControllerId()).contains(event.getPlayerId())) {
|
||||||
correctEndPhase = true;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CONTROLLER_ATTACHED_TO:
|
case CONTROLLER_ATTACHED_TO:
|
||||||
Permanent attachment = game.getPermanent(sourceId);
|
Permanent attachment = game.getPermanent(getSourceId());
|
||||||
if (attachment != null && attachment.getAttachedTo() != null) {
|
if (attachment == null || attachment.getAttachedTo() == null) {
|
||||||
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
return false;
|
||||||
if (attachedTo != null && attachedTo.isControlledBy(event.getPlayerId())) {
|
|
||||||
correctEndPhase = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
|
||||||
|
if (attachedTo == null || !attachedTo.isControlledBy(event.getPlayerId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("TargetController not supported");
|
||||||
}
|
}
|
||||||
if (correctEndPhase) {
|
return condition == null || condition.apply(game, this);
|
||||||
return !(condition != null && !condition.apply(game, this));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,23 +84,17 @@ public class AtTheBeginOfNextEndStepDelayedTriggeredAbility extends DelayedTrigg
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRule() {
|
public String getTriggerPhrase() {
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
switch (targetController) {
|
switch (targetController) {
|
||||||
case YOU:
|
case YOU:
|
||||||
sb.append("At the beginning of your next end step, ");
|
return "At the beginning of your next end step, ";
|
||||||
break;
|
|
||||||
case OPPONENT:
|
case OPPONENT:
|
||||||
sb.append("At the beginning of an opponent's next end step, ");
|
return "At the beginning of an opponent's next end step, ";
|
||||||
break;
|
|
||||||
case ANY:
|
case ANY:
|
||||||
sb.append("At the beginning of the next end step, ");
|
return "At the beginning of the next end step, ";
|
||||||
break;
|
|
||||||
case CONTROLLER_ATTACHED_TO:
|
case CONTROLLER_ATTACHED_TO:
|
||||||
sb.append("At the beginning of the next end step of enchanted creature's controller, ");
|
return "At the beginning of the next end step of enchanted creature's controller, ";
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
sb.append(getEffects().getText(modes.getMode()));
|
throw new UnsupportedOperationException("TargetController not supported");
|
||||||
return sb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
package mage.abilities.condition.common;
|
package mage.abilities.condition.common;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.condition.Condition;
|
import mage.abilities.condition.Condition;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As long as the sourceId permanent is
|
* As long as the sourceId permanent is
|
||||||
* on the battlefield, the condition is true.
|
* on the battlefield, the condition is true.
|
||||||
|
@ -13,18 +11,15 @@ import mage.game.Game;
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public enum SourceOnBattlefieldCondition implements Condition {
|
public enum SourceOnBattlefieldCondition implements Condition {
|
||||||
|
|
||||||
instance;
|
instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
return (game.getPermanent(source.getSourceId()) != null);
|
return source.getSourcePermanentIfItStillExists(game) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "if {this} is on the battlefield";
|
return "if {this} is on the battlefield";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,7 @@ public class CreateDelayedTriggeredAbilityEffect extends OneShotEffect {
|
||||||
DelayedTriggeredAbility delayedAbility = ability.copy();
|
DelayedTriggeredAbility delayedAbility = ability.copy();
|
||||||
if (this.copyTargets) {
|
if (this.copyTargets) {
|
||||||
if (source.getTargets().isEmpty()) {
|
if (source.getTargets().isEmpty()) {
|
||||||
for (Effect effect : delayedAbility.getEffects()) {
|
delayedAbility.getEffects().setTargetPointer(targetPointer);
|
||||||
effect.setTargetPointer(targetPointer);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
delayedAbility.getTargets().addAll(source.getTargets());
|
delayedAbility.getTargets().addAll(source.getTargets());
|
||||||
for (Effect effect : delayedAbility.getEffects()) {
|
for (Effect effect : delayedAbility.getEffects()) {
|
||||||
|
|
|
@ -93,7 +93,7 @@ class DarettiScrapSavantEffect extends OneShotEffect {
|
||||||
Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect();
|
Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect();
|
||||||
effect.setTargetPointer(new FixedTarget(card, game));
|
effect.setTargetPointer(new FixedTarget(card, game));
|
||||||
effect.setText("return that card to the battlefield at the beginning of the next end step");
|
effect.setText("return that card to the battlefield at the beginning of the next end step");
|
||||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.COMMAND, effect, TargetController.ANY), source);
|
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, TargetController.ANY), source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -53,7 +53,7 @@ class LilianaDefiantNecromancerEmblemEffect extends OneShotEffect {
|
||||||
Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect();
|
Effect effect = new ReturnFromGraveyardToBattlefieldTargetEffect();
|
||||||
effect.setTargetPointer(new FixedTarget(card, game));
|
effect.setTargetPointer(new FixedTarget(card, game));
|
||||||
effect.setText("return that card to the battlefield at the beginning of the next end step");
|
effect.setText("return that card to the battlefield at the beginning of the next end step");
|
||||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.COMMAND, effect, TargetController.ANY), source);
|
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, TargetController.ANY), source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue