* Modal Double Faces cards - fixed that a second side can't be played from non hand zones in some cases (#7200);

Play lands from graveyard effect - reworked as AsThoughEffect;
This commit is contained in:
Oleg Agafonov 2020-11-23 02:30:54 +04:00
parent 24e2728fca
commit c1e7a08c68
9 changed files with 210 additions and 62 deletions

View file

@ -515,7 +515,15 @@ public class ContinuousEffects implements Serializable {
UUID idToCheck;
if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof SplitCardHalf) {
idToCheck = ((SplitCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId();
} else if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof ModalDoubleFacesCardHalf) {
} else if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof ModalDoubleFacesCardHalf
&& !type.needPlayCardAbility()) {
// each mdf side uses own characteristics to check for playing, all other cases must use main card
// rules:
// "If an effect allows you to play a land or cast a spell from among a group of cards,
// you may play or cast a modal double-faced card with any face that fits the criteria
// of that effect. For example, if Sejiri Shelter / Sejiri Glacier is in your graveyard
// and an effect allows you to play lands from your graveyard, you could play Sejiri Glacier.
// That effect doesn't allow you to cast Sejiri Shelter."
idToCheck = ((ModalDoubleFacesCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId();
} else if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof AdventureCardSpell
&& !type.needPlayCardAbility()) {
@ -525,7 +533,9 @@ public class ContinuousEffects implements Serializable {
Card card = game.getCard(objectId);
if (card instanceof SplitCardHalf) {
idToCheck = ((SplitCardHalf) card).getParentCard().getId();
} else if (card instanceof ModalDoubleFacesCardHalf) {
} else if (card instanceof ModalDoubleFacesCardHalf
&& !type.needPlayCardAbility()) {
// each mdf side uses own characteristics to check for playing, all other cases must use main card
idToCheck = ((ModalDoubleFacesCardHalf) card).getParentCard().getId();
} else if (card instanceof AdventureCardSpell
&& !type.needPlayCardAbility()) {

View file

@ -0,0 +1,78 @@
package mage.abilities.effects.common.ruleModifying;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.cards.Card;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterCard;
import mage.filter.common.FilterLandCard;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author JayDi85
*/
public class PlayLandsFromGraveyardControllerEffect extends AsThoughEffectImpl {
private final FilterCard filter;
public PlayLandsFromGraveyardControllerEffect() {
this(new FilterLandCard("lands"));
}
public PlayLandsFromGraveyardControllerEffect(FilterCard filter) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
this.filter = filter;
staticText = "You may play " + filter.getMessage() + " from your graveyard";
}
public PlayLandsFromGraveyardControllerEffect(final PlayLandsFromGraveyardControllerEffect effect) {
super(effect);
this.filter = effect.filter;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public PlayLandsFromGraveyardControllerEffect copy() {
return new PlayLandsFromGraveyardControllerEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return applies(objectId, null, source, game, affectedControllerId);
}
@Override
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game, UUID playerId) {
Card cardToCheck = game.getCard(objectId);
objectId = CardUtil.getMainCardId(game, objectId); // for split cards
if (cardToCheck == null) {
return false;
}
Player player = game.getPlayer(cardToCheck.getOwnerId());
if (player == null) {
return false;
}
UUID needCardId = objectId;
if (player.getGraveyard().getCards(game).stream().noneMatch(c -> c.getId().equals(needCardId))) {
return false;
}
return playerId.equals(source.getControllerId())
&& cardToCheck.isOwnedBy(source.getControllerId())
&& (!cardToCheck.getManaCost().isEmpty() || cardToCheck.isLand())
&& filter.match(cardToCheck, game);
}
}

View file

@ -1,46 +0,0 @@
package mage.abilities.effects.common.ruleModifying;
import mage.abilities.Ability;
import mage.abilities.common.PlayLandFromGraveyardAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.players.Player;
public class PlayLandsFromGraveyardEffect extends ContinuousEffectImpl {
public PlayLandsFromGraveyardEffect() {
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.staticText = "You may play lands from your graveyard";
}
public PlayLandsFromGraveyardEffect(final PlayLandsFromGraveyardEffect effect) {
super(effect);
}
@Override
public PlayLandsFromGraveyardEffect copy() {
return new PlayLandsFromGraveyardEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
for (Card card : player.getGraveyard().getCards(game)) {
if (card != null && card.isLand()) {
PlayLandFromGraveyardAbility ability = new PlayLandFromGraveyardAbility(card.getName());
ability.setSourceId(card.getId());
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability);
}
}
return true;
}
return false;
}
}