From 2f138a04ae67423d39524fc428264539010a7b94 Mon Sep 17 00:00:00 2001 From: Patrick Hulin Date: Tue, 10 Dec 2019 13:33:27 -0500 Subject: [PATCH] Fix issue with casting opponents' cards. --- .../cards/cost/adventure/AdventureCardsTest.java | 4 ++-- .../abilities/effects/ContinuousEffects.java | 12 ++++++------ .../common/ExileAdventureSpellEffect.java | 5 +++-- .../java/mage/cards/AdventureCardSpellImpl.java | 16 ++++++++++++---- Mage/src/main/java/mage/players/PlayerImpl.java | 15 +++++++++++---- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java index 8cf9ca61e1f..4159852c7fd 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/adventure/AdventureCardsTest.java @@ -269,9 +269,9 @@ public class AdventureCardsTest extends CardTestPlayerBase { * You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell. */ setStrictChooseMode(true); - addCard(Zone.BATTLEFIELD, playerA, "Island", 4); + addCard(Zone.BATTLEFIELD, playerA, "Island", 1); addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); - addCard(Zone.BATTLEFIELD, playerA, "Forest", 3); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); addCard(Zone.HAND, playerA, "Psychic Intrusion"); addCard(Zone.HAND, playerB, "Curious Pair"); diff --git a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java index 5d3456dc21f..74eaa870060 100644 --- a/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/main/java/mage/abilities/effects/ContinuousEffects.java @@ -5,10 +5,7 @@ import mage.MageObjectReference; import mage.abilities.*; import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect; import mage.abilities.effects.common.continuous.CommanderReplacementEffect; -import mage.cards.Card; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.cards.SplitCardHalf; +import mage.cards.*; import mage.constants.*; import mage.filter.FilterCard; import mage.filter.predicate.Predicate; @@ -509,8 +506,11 @@ public class ContinuousEffects implements Serializable { if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof SplitCardHalf) { idToCheck = ((SplitCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId(); } else { - if (game.getObject(objectId) instanceof SplitCardHalf) { - idToCheck = ((SplitCardHalf) game.getObject(objectId)).getParentCard().getId(); + Card card = game.getCard(objectId); + if (card != null && card instanceof SplitCardHalf) { + idToCheck = ((SplitCardHalf) card).getParentCard().getId(); + } else if (card != null && card instanceof AdventureCardSpell) { + idToCheck = ((AdventureCardSpell) card).getParentCard().getId(); } else { idToCheck = objectId; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java index 9c1cb072055..abc8b88b923 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAdventureSpellEffect.java @@ -55,9 +55,10 @@ public class ExileAdventureSpellEffect extends OneShotEffect implements MageSing UUID exileId = adventureExileId(controller.getId(), game); game.getExile().createZone(exileId, "On an Adventure"); AdventureCardSpell adventureSpellCard = (AdventureCardSpell) spellCard; - if (controller.moveCardsToExile(adventureSpellCard, source, game, true, exileId, "On an Adventure")) { + Card parentCard = adventureSpellCard.getParentCard(); + if (controller.moveCardsToExile(parentCard, source, game, true, exileId, "On an Adventure")) { ContinuousEffect effect = new AdventureCastFromExileEffect(); - effect.setTargetPointer(new FixedTarget(adventureSpellCard.getParentCard().getId(), game)); + effect.setTargetPointer(new FixedTarget(parentCard.getId(), game)); game.addEffect(effect, source); } } diff --git a/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java b/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java index 2b970627c26..16b94a10dbc 100644 --- a/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java +++ b/Mage/src/main/java/mage/cards/AdventureCardSpellImpl.java @@ -111,11 +111,14 @@ class AdventureCardSpellAbility extends SpellAbility { @Override public ActivationStatus canActivate(UUID playerId, Game game) { ExileZone adventureExileZone = game.getExile().getExileZone(ExileAdventureSpellEffect.adventureExileId(playerId, game)); - if (adventureExileZone != null && adventureExileZone.contains(this.getSourceId())) { - return ActivationStatus.getFalse(); - } else { - return super.canActivate(playerId, game); + Card spellCard = game.getCard(this.getSourceId()); + if (spellCard != null && spellCard instanceof AdventureCardSpell) { + Card card = ((AdventureCardSpell) spellCard).getParentCard(); + if (adventureExileZone != null && adventureExileZone.contains(card.getId())) { + return ActivationStatus.getFalse(); + } } + return super.canActivate(playerId, game); } public void setName(String name, String costs) { @@ -144,4 +147,9 @@ class AdventureCardSpellAbility extends SpellAbility { sbRule.append(" (Then exile this card. You may cast the creature later from exile.)"); return sbRule.toString(); } + + @Override + public SpellAbility copy() { + return new AdventureCardSpellAbility(this); + } } \ No newline at end of file diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index e302a66c1da..2bb2bc642bc 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -3218,10 +3218,14 @@ public abstract class PlayerImpl implements Player, Serializable { } } - private List cardPlayableAbilities(Game game, Card card) { + private List cardPlayableAbilities(Game game, Card card, boolean setControllerId) { List playable = new ArrayList(); if (card != null) { for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) { + if (setControllerId) { + // For when owner != caster, e.g. with Psychic Intrusion and similar effects. + ability.setControllerId(getId()); + } if (ability instanceof SpellAbility && null != game.getContinuousEffects().asThough(card.getId(), AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, ability, getId(), game)) { @@ -3231,6 +3235,9 @@ public abstract class PlayerImpl implements Player, Serializable { AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, card.getSpellAbility(), getId(), game)) { playable.add(ability); } + if (setControllerId) { + ability.setControllerId(card.getOwnerId()); + } } } return playable; @@ -3312,7 +3319,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)) { - playable.addAll(cardPlayableAbilities(game, card)); + playable.addAll(cardPlayableAbilities(game, card, true)); } } } @@ -3321,7 +3328,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (fromAll) { for (Cards revealedCards : game.getState().getRevealed().values()) { for (Card card : revealedCards.getCards(game)) { - playable.addAll(cardPlayableAbilities(game, card)); + playable.addAll(cardPlayableAbilities(game, card, false)); } } } @@ -3333,7 +3340,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (player != null) { if (/*player.isTopCardRevealed() &&*/player.getLibrary().hasCards()) { Card card = player.getLibrary().getFromTop(game); - playable.addAll(cardPlayableAbilities(game, card)); + playable.addAll(cardPlayableAbilities(game, card, false)); } } }