* Chained to the Rocks - Fixed that target was also exiled if Chained to the Rocks was no more on the battlefield as the exile effect resolves.

This commit is contained in:
LevelX2 2014-02-23 12:19:59 +01:00
parent 116a7ba6ec
commit 6f5d789057

View file

@ -29,18 +29,18 @@ package mage.sets.theros;
import java.util.LinkedList;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.keyword.EnchantAbility;
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;
@ -52,11 +52,39 @@ 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.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.WatcherImpl;
/**
* If the land Chained to the Rocks is enchanting stops being a Mountain or another player
* gains control of it, Chained to the Rocks will be put into its owner's graveyard when
* state-based actions are performed.
*
* Chained to the Rocks's ability causes a zone change with a duration, a style of ability
* introduced in Magic 2014 that's somewhat reminiscent of older cards like Oblivion Ring.
* However, unlike Oblivion Ring, cards like Chained to the Rocks have a single ability
* that creates two one-shot effects: one that exiles the creature when the ability resolves,
* and another that returns the exiled card to the battlefield immediately after Chained to
* the Rocks leaves the battlefield.
*
* If Chained to the Rocks leaves the battlefield before its triggered ability resolves,
* the target creature won't be exiled.
*
* Auras attached to the exiled creature will be put into their owners' graveyards (unless
* they have bestow). Equipment attached to the exiled creature will become unattached and
* remain on the battlefield. Any counters on the exiled creature will cease to exist.
*
* If a creature token is exiled, it ceases to exist. It won't be returned to the battlefield.
*
* The exiled card returns to the battlefield immediately after Chained to the Rocks leaves
* the battlefield. Nothing happens between the two events, including state-based actions.
*
* In a multiplayer game, if Chained to the Rocks's owner leaves the game, the exiled card
* will return to the battlefield. Because the one-shot effect that returns the card isn't
* an ability that goes on the stack, it won't cease to exist along with the leaving player's
* spells and abilities on the stack.
*
* @author LevelX2
*/
@ -68,7 +96,6 @@ public class ChainedToTheRocks extends CardImpl<ChainedToTheRocks> {
filter.add(new SubtypePredicate("Mountain"));
filterTarget.add(new ControllerPredicate(TargetController.OPPONENT));
}
private UUID exileId = UUID.randomUUID();
public ChainedToTheRocks(UUID ownerId) {
super(ownerId, 4, "Chained to the Rocks", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{W}");
@ -84,14 +111,11 @@ public class ChainedToTheRocks extends CardImpl<ChainedToTheRocks> {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// When Chained to the Rocks enters the battlefield, exile target creature an opponent controls until Chained to the Rocks leaves the battlefield. (That creature returns under its owner's control.)
Effect effect = new ExileTargetEffect(exileId, this.getName());
effect.setText("exile target creature an opponent controls until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>");
ability = new EntersBattlefieldTriggeredAbility(effect);
ability = new EntersBattlefieldTriggeredAbility(new ChainedToTheRocksEffect());
ability.addTarget(new TargetCreaturePermanent(filterTarget));
this.addAbility(ability);
this.addWatcher(new ChainedToTheRocksWatcher(exileId));
this.addWatcher(new ChainedToTheRocksWatcher(this.getId()));
}
@ -105,32 +129,57 @@ public class ChainedToTheRocks extends CardImpl<ChainedToTheRocks> {
}
}
class ChainedToTheRocksEffect extends OneShotEffect<ChainedToTheRocksEffect> {
public ChainedToTheRocksEffect() {
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 ChainedToTheRocksEffect(final ChainedToTheRocksEffect effect) {
super(effect);
}
@Override
public ChainedToTheRocksEffect copy() {
return new ChainedToTheRocksEffect(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 ChainedToTheRocksWatcher extends WatcherImpl<ChainedToTheRocksWatcher> {
private UUID exileId;
ChainedToTheRocksWatcher (UUID exileId) {
super("BattlefieldLeft", WatcherScope.CARD);
this.exileId = exileId;
}
ChainedToTheRocksWatcher(final ChainedToTheRocksWatcher 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();
}