diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 406a61fad43..629b54081a2 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -882,6 +882,17 @@ public final class StaticAbilityContinuous { affectedCard.setMayPlay(mayPlayController, mayPlayWithoutManaCost, mayPlayAltCost != null ? new Cost(mayPlayAltCost, false) : null, mayPlayWithFlash, mayPlayGrantZonePermissions, stAb); + + // If the MayPlay effect only affected itself, check if it is in graveyard and give other player who cast Shaman's Trance MayPlay + if (stAb.getParam("Affected").equals("Card.Self") && affectedCard.isInZone(ZoneType.Graveyard)) { + for (final Player p : game.getPlayers()) { + if (p.hasKeyword("Shaman's Trance") && mayPlayController != p) { + affectedCard.setMayPlay(p, mayPlayWithoutManaCost, + mayPlayAltCost != null ? new Cost(mayPlayAltCost, false) : null, + mayPlayWithFlash, mayPlayGrantZonePermissions, stAb); + } + } + } } } @@ -979,7 +990,26 @@ public final class StaticAbilityContinuous { affectedCards.addAll(game.getCardsIn(ZoneType.Battlefield)); } if (stAb.hasParam("Affected")) { + // Handle Shaman's Trance + CardCollection affectedCardsOriginal = null; + if (controller.hasKeyword("Shaman's Trance") && stAb.hasParam("MayPlay")) { + affectedCardsOriginal = new CardCollection(affectedCards); + } + affectedCards = CardLists.getValidCards(affectedCards, stAb.getParam("Affected").split(","), controller, hostCard, stAb); + + // Add back all cards that are in other player's graveyard, and meet the restrictions without YouOwn/YouCtrl (treat it as in your graveyard) + if (affectedCardsOriginal != null) { + String affectedParam = stAb.getParam("Affected"); + affectedParam = affectedParam.replaceAll("[\\.\\+]YouOwn", ""); + affectedParam = affectedParam.replaceAll("[\\.\\+]YouCtrl", ""); + String[] restrictions = affectedParam.split(","); + for (final Card card : affectedCardsOriginal) { + if (card.isInZone(ZoneType.Graveyard) && card.getController() != controller && card.isValid(restrictions, controller, hostCard, stAb)) { + affectedCards.add(card); + } + } + } } affectedCards.removeAll(stAb.getIgnoreEffectCards()); diff --git a/forge-gui/res/cardsfolder/s/shamans_trance.txt b/forge-gui/res/cardsfolder/s/shamans_trance.txt new file mode 100644 index 00000000000..187593e172b --- /dev/null +++ b/forge-gui/res/cardsfolder/s/shamans_trance.txt @@ -0,0 +1,10 @@ +Name:Shaman's Trance +ManaCost:2 R +Types:Instant +A:SP$ Effect | Cost$ 2 R | StaticAbilities$ STCantPlayLand,STCantCastSpell,STTrance | SpellDescription$ Other players can't play lands or cast spells from their graveyards this turn. You may play lands and cast spells from other players' graveyards this turn as though those cards were in your graveyard. +SVar:STCantPlayLand:Mode$ CantPlayLand | ValidCard$ Land | Origin$ Graveyard | Player$ Player.Other | EffectZone$ Command | Description$ Other players can't play lands from their graveyards this turn. +SVar:STCantCastSpell:Mode$ CantBeCast | ValidCard$ Card | Origin$ Graveyard | Caster$ Player.Other | EffectZone$ Command | Description$ Other players cast spells from their graveyards this turn. +SVar:STTrance:Mode$ Continuous | Affected$ You | AddKeyword$ Shaman's Trance | Description$ You may play lands and cast spells from other players' graveyards this turn as though those cards were in your graveyard. +AI:RemoveDeck:All +AI:RemoveDeck:Random +Oracle:Other players can't play lands or cast spells from their graveyards this turn. You may play lands and cast spells from other players' graveyards this turn as though those cards were in your graveyard. diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index b425ebb3112..d960a62ceab 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -265,7 +265,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont public SpellAbility getAbilityToPlay(final Card hostCard, final List abilities, final ITriggerEvent triggerEvent) { // make sure another human player can't choose opponents cards just because he might see them - if (triggerEvent != null && !hostCard.isInZone(ZoneType.Battlefield) && !hostCard.getOwner().equals(player) && !hostCard.getController().equals(player) && hostCard.mayPlay(player).size() == 0) { + if (triggerEvent != null && !hostCard.isInZone(ZoneType.Battlefield) && !hostCard.getOwner().equals(player) && + !hostCard.getController().equals(player) && hostCard.mayPlay(player).size() == 0 && + // If player cast Shaman's Trance, they can play spells from any Graveyard (if other effects allow it to be cast) + (!player.hasKeyword("Shaman's Trance") || !hostCard.isInZone(ZoneType.Graveyard))) { return null; } spellViewCache = SpellAbilityView.getMap(abilities);