Fix behavior for Garruk's Horde, Melek, W6.

This commit is contained in:
Patrick Hulin 2019-12-10 11:34:19 -05:00
parent 19ca9f555c
commit cd890d329a
5 changed files with 192 additions and 35 deletions

View file

@ -2,7 +2,10 @@
package mage.abilities.effects.common.continuous;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.cards.Card;
import mage.constants.AsThoughEffectType;
@ -47,12 +50,27 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
@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 cardOnTop = game.getCard(objectId);
Card cardToCheckProperties = cardOnTop;
// Check each ability individually, as e.g. Adventures and associated creatures may get different results from the filter.
if (affectedAbility != null) {
MageObject sourceObject = affectedAbility.getSourceObject(game);
if (sourceObject != null && sourceObject instanceof Card) {
cardToCheckProperties = (Card) sourceObject;
}
}
if (cardOnTop != null
&& affectedControllerId.equals(source.getControllerId())
&& playerId.equals(source.getControllerId())
&& cardOnTop.isOwnedBy(source.getControllerId())
&& (!cardOnTop.getManaCost().isEmpty() || cardOnTop.isLand())
&& filter.match(cardOnTop, game)) {
&& (!cardToCheckProperties.getManaCost().isEmpty() || cardToCheckProperties.isLand())
&& filter.match(cardToCheckProperties, game)) {
Player player = game.getPlayer(cardOnTop.getOwnerId());
if (player != null && cardOnTop.equals(player.getLibrary().getFromTop(game))) {
return true;

View file

@ -21,7 +21,9 @@ public abstract class AdventureCard extends CardImpl {
public AdventureCard(UUID ownerId, CardSetInfo setInfo, CardType[] types, CardType[] typesSpell, String costs, String adventureName, String costsSpell) {
super(ownerId, setInfo, types, costs);
spellCard = new AdventureCardSpellImpl(ownerId, setInfo, adventureName, typesSpell, costsSpell, this);
this.addAbility(spellCard.getSpellAbility());
Ability adventureAbility = spellCard.getSpellAbility();
this.addAbility(adventureAbility);
adventureAbility.setSourceId(spellCard.getId());
}
public AdventureCard(AdventureCard card) {

View file

@ -4,6 +4,7 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.keyword.RetraceAbility;
import mage.cards.AdventureCard;
import mage.cards.Card;
import mage.constants.*;
import mage.game.Game;
@ -45,6 +46,10 @@ class WrennAndSixEmblemEffect extends ContinuousEffectImpl {
if (card == null || !card.isInstantOrSorcery()) {
continue;
}
if (card instanceof AdventureCard) {
// Adventure cards are castable per https://twitter.com/elishffrn/status/1179047911729946624
card = ((AdventureCard) card).getSpellCard();
}
Ability ability = new RetraceAbility(card);
ability.setSourceId(cardId);
ability.setControllerId(card.getOwnerId());

View file

@ -3218,6 +3218,24 @@ public abstract class PlayerImpl implements Player, Serializable {
}
}
private List<Ability> cardPlayableAbilities(Game game, Card card) {
List<Ability> playable = new ArrayList();
if (card != null) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
if (ability instanceof SpellAbility
&& null != game.getContinuousEffects().asThough(card.getId(),
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, ability, getId(), game)) {
playable.add(ability);
} else if (ability instanceof PlayLandAbility
&& null != game.getContinuousEffects().asThough(card.getId(),
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), getId(), game)) {
playable.add(ability);
}
}
}
return playable;
}
@Override
public List<Ability> getPlayable(Game game, boolean hidden) {
return getPlayable(game, hidden, Zone.ALL, true);
@ -3294,20 +3312,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (fromAll || fromZone == Zone.EXILED) {
for (ExileZone exile : game.getExile().getExileZones()) {
for (Card card : exile.getCards(game)) {
if (null != game.getContinuousEffects().asThough(card.getId(),
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game)) {
for (Ability ability : card.getAbilities()) {
if (ability.getZone().match(Zone.HAND)) {
ability.setControllerId(this.getId()); // controller must be set for case owner != caster
if (ability instanceof ActivatedAbility) {
if (((ActivatedAbility) ability).canActivate(playerId, game).canActivate()) {
playable.add(ability);
}
}
ability.setControllerId(card.getOwnerId());
}
}
}
playable.addAll(cardPlayableAbilities(game, card));
}
}
}
@ -3316,14 +3321,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (fromAll) {
for (Cards revealedCards : game.getState().getRevealed().values()) {
for (Card card : revealedCards.getCards(game)) {
if (null != game.getContinuousEffects().asThough(card.getId(),
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, null, this.getId(), game)) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) {
playable.add(ability);
}
}
}
playable.addAll(cardPlayableAbilities(game, card));
}
}
}
@ -3335,14 +3333,7 @@ public abstract class PlayerImpl implements Player, Serializable {
if (player != null) {
if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) {
Card card = player.getLibrary().getFromTop(game);
if (card != null && null != game.getContinuousEffects().asThough(card.getId(),
AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), getId(), game)) {
for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
if (ability instanceof SpellAbility || ability instanceof PlayLandAbility) {
playable.add(ability);
}
}
}
playable.addAll(cardPlayableAbilities(game, card));
}
}
}