mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
* 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:
parent
116a7ba6ec
commit
6f5d789057
1 changed files with 66 additions and 17 deletions
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue