mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
* Blazing Shoal, Banisher Priest, Colossal Whale - Fixed that target was wrongly also exiled if source permanent was no more on the battlefield as the exile effect resolves.
This commit is contained in:
parent
6f5d789057
commit
22fccea168
3 changed files with 109 additions and 61 deletions
|
@ -32,8 +32,11 @@ import mage.constants.CardType;
|
|||
import mage.constants.Duration;
|
||||
import mage.constants.Rarity;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.costs.AlternativeCostImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.common.ExileFromHandCost;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.dynamicvalue.common.ExileFromHandCostCardConvertedMana;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.common.continious.BoostTargetEffect;
|
||||
|
@ -42,6 +45,7 @@ import mage.filter.common.FilterOwnedCard;
|
|||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.mageobject.CardIdPredicate;
|
||||
import mage.filter.predicate.mageobject.ColorPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
|
@ -51,8 +55,6 @@ import mage.target.common.TargetCreaturePermanent;
|
|||
*/
|
||||
public class BlazingShoal extends CardImpl<BlazingShoal> {
|
||||
|
||||
private static final String ALTERNATIVE_COST_DESCRIPTION = "You may exile a red card with converted mana cost X from your hand rather than pay Blazing Shoal's mana cost";
|
||||
|
||||
public BlazingShoal(UUID ownerId) {
|
||||
super(ownerId, 96, "Blazing Shoal", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{X}{R}{R}");
|
||||
this.expansionSetCode = "BOK";
|
||||
|
@ -63,7 +65,10 @@ public class BlazingShoal extends CardImpl<BlazingShoal> {
|
|||
FilterOwnedCard filter = new FilterOwnedCard("red card from your hand");
|
||||
filter.add(new ColorPredicate(ObjectColor.RED));
|
||||
filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself
|
||||
this.getSpellAbility().addAlternativeCost(new AlternativeCostImpl(ALTERNATIVE_COST_DESCRIPTION, new ExileFromHandCost(new TargetCardInHand(filter))));
|
||||
|
||||
AlternativeCostSourceAbility ability = new BlazingShoalAlternativeCostAbility(new PayLifeCost(1));
|
||||
ability.addCost(new ExileFromHandCost(new TargetCardInHand(filter)));
|
||||
this.addAbility(ability);
|
||||
|
||||
// Target creature gets +X/+0 until end of turn.
|
||||
this.getSpellAbility().addEffect(new BoostTargetEffect(new ExileFromHandCostCardConvertedMana(), new StaticValue(0), Duration.EndOfTurn));
|
||||
|
@ -78,4 +83,20 @@ public class BlazingShoal extends CardImpl<BlazingShoal> {
|
|||
public BlazingShoal copy() {
|
||||
return new BlazingShoal(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BlazingShoalAlternativeCostAbility extends AlternativeCostSourceAbility {
|
||||
|
||||
public BlazingShoalAlternativeCostAbility(Cost cost) {
|
||||
super(cost, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean askToActivateAlternativeCosts(Ability ability, Game game) {
|
||||
if (super.askToActivateAlternativeCosts(ability, game)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,21 +30,25 @@ package mage.sets.magic2014;
|
|||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.filter.predicate.permanent.ControllerPredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.watchers.WatcherImpl;
|
||||
|
||||
|
@ -54,7 +58,10 @@ import mage.watchers.WatcherImpl;
|
|||
*/
|
||||
public class BanisherPriest extends CardImpl<BanisherPriest> {
|
||||
|
||||
private UUID exileId = UUID.randomUUID();
|
||||
private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls");
|
||||
static {
|
||||
filter.add(new ControllerPredicate(TargetController.OPPONENT));
|
||||
}
|
||||
|
||||
public BanisherPriest(UUID ownerId) {
|
||||
super(ownerId, 7, "Banisher Priest", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
|
||||
|
@ -67,8 +74,10 @@ public class BanisherPriest extends CardImpl<BanisherPriest> {
|
|||
this.toughness = new MageInt(2);
|
||||
|
||||
// When Banisher Priest enters the battlefield, exile target creature an opponent controls until Banisher Priest leaves the battlefield.
|
||||
this.addAbility(new BanisherPriestTriggeredAbility(exileId));
|
||||
this.addWatcher(new BanisherPriestWatcher(exileId));
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new BanisherPriestExileEffect());
|
||||
ability.addTarget(new TargetCreaturePermanent(filter, true));
|
||||
this.addAbility(ability);
|
||||
this.addWatcher(new BanisherPriestWatcher());
|
||||
|
||||
}
|
||||
|
||||
|
@ -82,67 +91,57 @@ public class BanisherPriest extends CardImpl<BanisherPriest> {
|
|||
}
|
||||
}
|
||||
|
||||
class BanisherPriestTriggeredAbility extends TriggeredAbilityImpl<BanisherPriestTriggeredAbility> {
|
||||
class BanisherPriestExileEffect extends OneShotEffect<BanisherPriestExileEffect> {
|
||||
|
||||
public BanisherPriestTriggeredAbility(UUID exileId) {
|
||||
super(Zone.BATTLEFIELD, null, false);
|
||||
this.addEffect(new ExileTargetEffect(exileId, "Banisher Priest"));
|
||||
public BanisherPriestExileEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "exile target creature an opponent controls until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>";
|
||||
}
|
||||
|
||||
public BanisherPriestTriggeredAbility(final BanisherPriestTriggeredAbility ability) {
|
||||
super(ability);
|
||||
public BanisherPriestExileEffect(final BanisherPriestExileEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId())) {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls");
|
||||
filter.add(Predicates.not(new ControllerIdPredicate(controllerId)));
|
||||
this.getTargets().clear();
|
||||
TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
|
||||
target.setRequired(true);
|
||||
this.addTarget(target);
|
||||
return true;
|
||||
public BanisherPriestExileEffect copy() {
|
||||
return new BanisherPriestExileEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
// If Banisher Priest leaves the battlefield before its triggered ability resolves,
|
||||
// the target creature won't be exiled.
|
||||
if (permanent != null) {
|
||||
new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever {this} enters the battlefield, exile target creature an opponent controls until Banisher Priest leaves the battlefield.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public BanisherPriestTriggeredAbility copy() {
|
||||
return new BanisherPriestTriggeredAbility(this);
|
||||
}
|
||||
}
|
||||
|
||||
class BanisherPriestWatcher extends WatcherImpl<BanisherPriestWatcher> {
|
||||
|
||||
UUID exileId;
|
||||
|
||||
BanisherPriestWatcher(UUID exileId) {
|
||||
BanisherPriestWatcher() {
|
||||
super("BattlefieldLeft", WatcherScope.CARD);
|
||||
this.exileId = exileId;
|
||||
}
|
||||
|
||||
BanisherPriestWatcher(final BanisherPriestWatcher watcher) {
|
||||
super(watcher);
|
||||
this.exileId = watcher.exileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
ExileZone exile = game.getExile().getExileZone(exileId);
|
||||
if (exile != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<UUID>(exile);
|
||||
ExileZone exile = game.getExile().getExileZone(this.getSourceId());
|
||||
Card sourceCard = game.getCard(this.getSourceId());
|
||||
if (exile != null && sourceCard != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId : cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, this.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" was returned to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
}
|
||||
|
|
|
@ -30,12 +30,15 @@ package mage.sets.magic2014;
|
|||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.abilities.keyword.IslandwalkAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.WatcherScope;
|
||||
import mage.constants.Zone;
|
||||
|
@ -45,6 +48,7 @@ import mage.game.ExileZone;
|
|||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.watchers.WatcherImpl;
|
||||
|
||||
|
@ -54,8 +58,6 @@ import mage.watchers.WatcherImpl;
|
|||
*/
|
||||
public class ColossalWhale extends CardImpl<ColossalWhale> {
|
||||
|
||||
private UUID exileId = UUID.randomUUID();
|
||||
|
||||
public ColossalWhale(UUID ownerId) {
|
||||
super(ownerId, 48, "Colossal Whale", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{U}{U}");
|
||||
this.expansionSetCode = "M14";
|
||||
|
@ -68,8 +70,8 @@ public class ColossalWhale extends CardImpl<ColossalWhale> {
|
|||
// Islandwalk
|
||||
this.addAbility(new IslandwalkAbility());
|
||||
// Whenever Colossal Whale attacks, you may exile target creature defending player controls until Colossal Whale leaves the battlefield.
|
||||
this.addAbility(new ColossalWhaleAbility(exileId));
|
||||
this.addWatcher(new ColossalWhaleWatcher(exileId));
|
||||
this.addAbility(new ColossalWhaleAbility());
|
||||
this.addWatcher(new ColossalWhaleWatcher());
|
||||
|
||||
|
||||
}
|
||||
|
@ -86,9 +88,9 @@ public class ColossalWhale extends CardImpl<ColossalWhale> {
|
|||
|
||||
class ColossalWhaleAbility extends TriggeredAbilityImpl<ColossalWhaleAbility> {
|
||||
|
||||
public ColossalWhaleAbility(UUID exileId) {
|
||||
public ColossalWhaleAbility() {
|
||||
super(Zone.BATTLEFIELD, null);
|
||||
this.addEffect(new ExileTargetEffect(exileId,"Colossal Whale"));
|
||||
this.addEffect(new ColossalWhaleExileEffect());
|
||||
}
|
||||
|
||||
public ColossalWhaleAbility(final ColossalWhaleAbility ability) {
|
||||
|
@ -113,7 +115,7 @@ class ColossalWhaleAbility extends TriggeredAbilityImpl<ColossalWhaleAbility> {
|
|||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "Whenever {this} attacks, you may exile target creature defending player controls until {this} leaves the battlefield.";
|
||||
return new StringBuilder("Whenever {this} attacks, ").append(super.getRule()).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -122,31 +124,57 @@ class ColossalWhaleAbility extends TriggeredAbilityImpl<ColossalWhaleAbility> {
|
|||
}
|
||||
}
|
||||
|
||||
class ColossalWhaleExileEffect extends OneShotEffect<ColossalWhaleExileEffect> {
|
||||
|
||||
public ColossalWhaleExileEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "you may exile target creature defending player controls until {this} leaves the battlefield";
|
||||
}
|
||||
|
||||
public ColossalWhaleExileEffect(final ColossalWhaleExileEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColossalWhaleExileEffect copy() {
|
||||
return new ColossalWhaleExileEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
||||
// If Chained to the Rocks leaves the battlefield before its triggered ability resolves,
|
||||
// the target creature won't be exiled.
|
||||
if (permanent != null) {
|
||||
new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ColossalWhaleWatcher extends WatcherImpl<ColossalWhaleWatcher> {
|
||||
|
||||
private UUID exileId;
|
||||
|
||||
ColossalWhaleWatcher (UUID exileId) {
|
||||
ColossalWhaleWatcher () {
|
||||
super("BattlefieldLeft", WatcherScope.CARD);
|
||||
this.exileId = exileId;
|
||||
}
|
||||
|
||||
ColossalWhaleWatcher(final ColossalWhaleWatcher watcher) {
|
||||
super(watcher);
|
||||
this.exileId = watcher.exileId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void watch(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(sourceId)) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent)event;
|
||||
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
|
||||
ExileZone exile = game.getExile().getExileZone(exileId);
|
||||
if (exile != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<UUID>(exile);
|
||||
ExileZone exile = game.getExile().getExileZone(this.getSourceId());
|
||||
Card sourceCard = game.getCard(this.getSourceId());
|
||||
if (exile != null && sourceCard != null) {
|
||||
LinkedList<UUID> cards = new LinkedList<>(exile);
|
||||
for (UUID cardId: cards) {
|
||||
Card card = game.getCard(cardId);
|
||||
card.moveToZone(Zone.BATTLEFIELD, this.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" was returned to battlefield from exile").toString());
|
||||
}
|
||||
exile.clear();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue