* Whip of Erebos - Fixed a bug that if target creature already left battlefield, the card was still moved to general exile zone (causing problems with Obzedat, Ghost council).

This commit is contained in:
LevelX2 2014-03-13 17:10:57 +01:00
parent d74921aa66
commit 9ca014b10e
4 changed files with 57 additions and 33 deletions

View file

@ -54,6 +54,7 @@ import mage.game.ExileZone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetOpponent;
/**
@ -128,7 +129,7 @@ class BeginningOfYourUpkeepdelayTriggeredAbility extends DelayedTriggeredAbility
public BeginningOfYourUpkeepdelayTriggeredAbility() {
this(new ObzedatGhostCouncilReturnEffect(), TargetController.YOU);
this.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.EndOfTurn));
this.addEffect(new GainAbilitySourceEffect(HasteAbility.getInstance(), Duration.Custom));
}
public BeginningOfYourUpkeepdelayTriggeredAbility(Effect effect, TargetController targetController) {
@ -141,10 +142,7 @@ class BeginningOfYourUpkeepdelayTriggeredAbility extends DelayedTriggeredAbility
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE && event.getPlayerId().equals(this.controllerId)) {
return true;
}
return false;
return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE && event.getPlayerId().equals(this.controllerId);
}
@Override
@ -180,7 +178,8 @@ class ObzedatGhostCouncilReturnEffect extends OneShotEffect<ObzedatGhostCouncilR
ExileZone currentZone = game.getState().getExile().getExileZone(source.getSourceId());
// return it only from the own exile zone
if (currentZone.size() > 0) {
if (card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), card.getOwnerId(), false)) {
Player owner = game.getPlayer(card.getOwnerId());
if (owner != null && owner.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId())) {
return true;
}
}

View file

@ -35,10 +35,12 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.AtEndOfTurnDelayedTriggeredAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.continious.GainAbilityControlledEffect;
import mage.abilities.effects.common.continious.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.Card;
@ -53,6 +55,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
@ -77,12 +80,9 @@ public class WhipOfErebos extends CardImpl<WhipOfErebos> {
// Activate this ability only any time you could cast a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new WhipOfErebosEffect(), new ManaCostsImpl("{2}{B}{B}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"), true));
ability.addEffect(new WhipOfErebosReplacementEffect());
this.addAbility(ability);
}
public WhipOfErebos(final WhipOfErebos card) {
@ -113,21 +113,25 @@ class WhipOfErebosEffect extends OneShotEffect<WhipOfErebosEffect> {
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(source.getFirstTarget());
if (card != null) {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && card != null) {
card.addAbility(HasteAbility.getInstance());
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
ExileTargetEffect exileEffect = new ExileTargetEffect();
exileEffect.setTargetPointer(new FixedTarget(card.getId()));
DelayedTriggeredAbility delayedAbility = new AtEndOfTurnDelayedTriggeredAbility(exileEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
game.addDelayedTriggeredAbility(delayedAbility);
if (controller.putOntoBattlefieldWithInfo(card, game, Zone.GRAVEYARD, source.getSourceId())) {
// gains haste
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
// Exile at begin of next end step
ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD);
exileEffect.setTargetPointer(new FixedTarget(card.getId()));
DelayedTriggeredAbility delayedAbility = new AtEndOfTurnDelayedTriggeredAbility(exileEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
game.addDelayedTriggeredAbility(delayedAbility);
}
return true;
}
return false;
}
}
@ -151,7 +155,7 @@ class WhipOfErebosReplacementEffect extends ReplacementEffectImpl<WhipOfErebosRe
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Card card = game.getCard(source.getFirstTarget());
if (card != null) {
if (card != null) {
card.moveToExile(null, "", source.getId(), game);
}
return true;

View file

@ -34,8 +34,10 @@ import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
@ -43,13 +45,19 @@ import mage.game.permanent.Permanent;
*/
public class ExileTargetEffect extends OneShotEffect<ExileTargetEffect> {
private Zone onlyFromZone;
private String exileZone = null;
private UUID exileId = null;
public ExileTargetEffect(UUID exileId, String exileZone) {
this();
public ExileTargetEffect(UUID exileId, String exileZone, Zone onlyFromZone) {
super(Outcome.Exile);
this.exileZone = exileZone;
this.exileId = exileId;
this.onlyFromZone = onlyFromZone;
}
public ExileTargetEffect(UUID exileId, String exileZone) {
this(exileId, exileZone, null);
}
public ExileTargetEffect(String effectText) {
@ -58,13 +66,14 @@ public class ExileTargetEffect extends OneShotEffect<ExileTargetEffect> {
}
public ExileTargetEffect() {
super(Outcome.Exile);
this(null, null);
}
public ExileTargetEffect(final ExileTargetEffect effect) {
super(effect);
this.exileZone = effect.exileZone;
this.exileId = effect.exileId;
this.onlyFromZone = effect.onlyFromZone;
}
@Override
@ -75,12 +84,21 @@ public class ExileTargetEffect extends OneShotEffect<ExileTargetEffect> {
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
return permanent.moveToExile(exileId, exileZone, source.getSourceId(), game);
} else {
Card card = game.getCard(targetPointer.getFirst(game, source));
if (card != null) {
return card.moveToExile(exileId, exileZone, source.getSourceId(), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
if (permanent != null) {
Zone currentZone = game.getState().getZone(permanent.getId());
if (!currentZone.equals(Zone.EXILED) && (onlyFromZone == null || onlyFromZone.equals(Zone.BATTLEFIELD))) {
return controller.moveCardToExileWithInfo(permanent, exileId, exileZone, source.getSourceId(), game, onlyFromZone);
}
} else {
Card card = game.getCard(targetPointer.getFirst(game, source));
if (card != null) {
Zone currentZone = game.getState().getZone(card.getId());
if (!currentZone.equals(Zone.EXILED) && (onlyFromZone == null || onlyFromZone.equals(currentZone))) {
return controller.moveCardToExileWithInfo(card, exileId, exileZone, source.getSourceId(), game, onlyFromZone);
}
}
}
}
return false;

View file

@ -2108,6 +2108,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
.append(" puts ").append(card.getName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")
.append("into his or her hand").toString());
result = true;
}
return result;
}
@ -2120,6 +2121,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
.append(" puts ").append(card.getName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")
.append("into his or her graveyard").toString());
result = true;
}
return result;
}
@ -2143,13 +2145,14 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
}
@Override
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) {
public boolean putOntoBattlefieldWithInfo(Card card, Game game, Zone fromZone, UUID sourceId, boolean tapped) {
boolean result = false;
if (card.putOntoBattlefield(game, fromZone, sourceId, this.getId(), tapped)) {
game.informPlayers(new StringBuilder(this.getName())
.append(" puts ").append(card.getName())
.append(" from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" ")
.append("onto the Battlefield").toString());
result = true;
}
return result;
}