Merge branch '908-mindbreak-trap-exiles-itself' into 'master'

Resolve "Mindbreak Trap Exiles itself"

Closes #908

See merge request core-developers/forge!1467
This commit is contained in:
Sol
2019-03-20 12:02:21 +00:00
3 changed files with 24 additions and 19 deletions

View File

@@ -173,8 +173,7 @@ public abstract class SpellAbilityEffect {
protected final static CardCollection getDefinedCardsOrTargeted(final SpellAbility sa, final String definedParam) { return getCards(true, definedParam, sa); } protected final static CardCollection getDefinedCardsOrTargeted(final SpellAbility sa, final String definedParam) { return getCards(true, definedParam, sa); }
private static CardCollection getCards(final boolean definedFirst, final String definedParam, final SpellAbility sa) { private static CardCollection getCards(final boolean definedFirst, final String definedParam, final SpellAbility sa) {
final boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam)) final boolean useTargets = sa.usesTargeting() && (!definedFirst || !sa.hasParam(definedParam));
&& sa.getTargets() != null && (sa.getTargets().isTargetingAnyCard() || sa.getTargets().getTargets().isEmpty());
return useTargets ? new CardCollection(sa.getTargets().getTargetCards()) return useTargets ? new CardCollection(sa.getTargets().getTargetCards())
: AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam(definedParam), sa); : AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam(definedParam), sa);
} }

View File

@@ -377,8 +377,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
* a {@link forge.game.spellability.SpellAbility} object. * a {@link forge.game.spellability.SpellAbility} object.
*/ */
private void changeKnownOriginResolve(final SpellAbility sa) { private void changeKnownOriginResolve(final SpellAbility sa) {
final boolean onlySpells = sa.hasParam("OnlySpells"); Iterable<Card> tgtCards = getTargetCards(sa);
Iterable<Card> tgtCards = !onlySpells ? getTargetCards(sa) : new CardCollection();
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Player player = sa.getActivatingPlayer(); final Player player = sa.getActivatingPlayer();
final Card hostCard = sa.getHostCard(); final Card hostCard = sa.getHostCard();
@@ -400,7 +399,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
altDest = true; altDest = true;
} }
} }
final CardZoneTable triggerList = new CardZoneTable();
// changing zones for spells on the stack // changing zones for spells on the stack
for (final SpellAbility tgtSA : getTargetSpells(sa)) { for (final SpellAbility tgtSA : getTargetSpells(sa)) {
if (!tgtSA.isSpell()) { // Catch any abilities or triggers that slip through somehow if (!tgtSA.isSpell()) { // Catch any abilities or triggers that slip through somehow
@@ -412,7 +412,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
continue; continue;
} }
removeFromStack(tgtSA, sa, si, game); removeFromStack(tgtSA, sa, si, game, triggerList);
} // End of change from stack } // End of change from stack
final String remember = sa.getParam("RememberChanged"); final String remember = sa.getParam("RememberChanged");
@@ -429,7 +429,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
final boolean optional = sa.hasParam("Optional"); final boolean optional = sa.hasParam("Optional");
final long ts = game.getNextTimestamp(); final long ts = game.getNextTimestamp();
final CardZoneTable triggerList = new CardZoneTable();
for (final Card tgtC : tgtCards) { for (final Card tgtC : tgtCards) {
if (tgt != null && tgtC.isInPlay() && !tgtC.canBeTargetedBy(sa)) { if (tgt != null && tgtC.isInPlay() && !tgtC.canBeTargetedBy(sa)) {
@@ -1183,36 +1182,39 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
* object. * object.
* @param game * @param game
*/ */
private static void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si, final Game game) { private static void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si, final Game game, CardZoneTable triggerList) {
final Card tgtHost = tgtSA.getHostCard();
final Zone originZone = tgtHost.getZone();
game.getStack().remove(si); game.getStack().remove(si);
Map<String,Object> params = Maps.newHashMap(); Map<String,Object> params = Maps.newHashMap();
params.put("StackSa", tgtSA); params.put("StackSa", tgtSA);
params.put("StackSi", si); params.put("StackSi", si);
Card movedCard = null;
if (srcSA.hasParam("Destination")) { if (srcSA.hasParam("Destination")) {
final boolean remember = srcSA.hasParam("RememberChanged"); final boolean remember = srcSA.hasParam("RememberChanged");
if (tgtSA.isAbility()) { if (tgtSA.isAbility()) {
// Shouldn't be able to target Abilities but leaving this in for now // Shouldn't be able to target Abilities but leaving this in for now
} else if (srcSA.getParam("Destination").equals("Graveyard")) { } else if (srcSA.getParam("Destination").equals("Graveyard")) {
game.getAction().moveToGraveyard(tgtSA.getHostCard(), srcSA, params); movedCard = game.getAction().moveToGraveyard(tgtHost, srcSA, params);
} else if (srcSA.getParam("Destination").equals("Exile")) { } else if (srcSA.getParam("Destination").equals("Exile")) {
Card host = srcSA.getOriginalHost(); Card host = srcSA.getOriginalHost();
if (host == null) { if (host == null) {
host = srcSA.getHostCard(); host = srcSA.getHostCard();
} }
tgtSA.getHostCard().setExiledWith(host); movedCard = game.getAction().exile(tgtHost, srcSA, params);
game.getAction().exile(tgtSA.getHostCard(), srcSA, params); movedCard.setExiledWith(host);
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) { } else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {
game.getAction().moveToLibrary(tgtSA.getHostCard(), srcSA, params); movedCard = game.getAction().moveToLibrary(tgtHost, srcSA, params);
} else if (srcSA.getParam("Destination").equals("Hand")) { } else if (srcSA.getParam("Destination").equals("Hand")) {
game.getAction().moveToHand(tgtSA.getHostCard(), srcSA, params); movedCard = game.getAction().moveToHand(tgtHost, srcSA, params);
} else if (srcSA.getParam("Destination").equals("BottomOfLibrary")) { } else if (srcSA.getParam("Destination").equals("BottomOfLibrary")) {
game.getAction().moveToBottomOfLibrary(tgtSA.getHostCard(), srcSA, params); movedCard = game.getAction().moveToBottomOfLibrary(tgtHost, srcSA, params);
} else if (srcSA.getParam("Destination").equals("Library")) { } else if (srcSA.getParam("Destination").equals("Library")) {
game.getAction().moveToBottomOfLibrary(tgtSA.getHostCard(), srcSA, params); movedCard = game.getAction().moveToBottomOfLibrary(tgtHost, srcSA, params);
if (srcSA.hasParam("Shuffle") && "True".equals(srcSA.getParam("Shuffle"))) { if (srcSA.hasParam("Shuffle") && "True".equals(srcSA.getParam("Shuffle"))) {
tgtSA.getHostCard().getOwner().shuffle(srcSA); tgtHost.getOwner().shuffle(srcSA);
} }
} else { } else {
throw new IllegalArgumentException("AbilityFactory_ChangeZone: Invalid Destination argument for card " throw new IllegalArgumentException("AbilityFactory_ChangeZone: Invalid Destination argument for card "
@@ -1220,12 +1222,16 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} }
if (remember) { if (remember) {
srcSA.getHostCard().addRemembered(tgtSA.getHostCard()); srcSA.getHostCard().addRemembered(tgtHost);
// TODO or remember moved?
} }
if (!tgtSA.isAbility()) { if (!tgtSA.isAbility()) {
System.out.println("Moving spell to " + srcSA.getParam("Destination")); System.out.println("Moving spell to " + srcSA.getParam("Destination"));
} }
if (originZone != null && movedCard != null) {
triggerList.put(originZone.getZoneType(), movedCard.getZone().getZoneType(), movedCard);
}
} }
} }
} }

View File

@@ -2,7 +2,7 @@ Name:Failure
ManaCost:1 U ManaCost:1 U
AlternateMode: Split AlternateMode: Split
Types:Instant Types:Instant
A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Card | OnlySpells$ True | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell to its owner's hand. A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell to its owner's hand.
SVar:Picture:http://www.wizards.com/global/images/magic/general/failure_comply.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/failure_comply.jpg
Oracle:Return target spell to its owner's hand. Oracle:Return target spell to its owner's hand.
@@ -15,4 +15,4 @@ K:Aftermath
A:SP$ NameCard | Cost$ W | Defined$ You | SubAbility$ DBEffect | SpellDescription$ Choose a card name. Until your next turn, your opponents can't cast spells with the chosen name. A:SP$ NameCard | Cost$ W | Defined$ You | SubAbility$ DBEffect | SpellDescription$ Choose a card name. Until your next turn, your opponents can't cast spells with the chosen name.
SVar:DBEffect:DB$ Effect | StaticAbilities$ CantCast | Duration$ UntilYourNextTurn SVar:DBEffect:DB$ Effect | StaticAbilities$ CantCast | Duration$ UntilYourNextTurn
SVar:CantCast:Mode$ CantBeCast | ValidCard$ Card.nonLand+NamedCard | Caster$ Opponent | EffectZone$ Command | Description$ Your opponents can't cast spells with the chosen name. SVar:CantCast:Mode$ CantBeCast | ValidCard$ Card.nonLand+NamedCard | Caster$ Opponent | EffectZone$ Command | Description$ Your opponents can't cast spells with the chosen name.
Oracle:Aftermath (Cast this spell only from your graveyard. Then exile it.)\nChoose a card name. Until your next turn, your opponents can't cast spells with the chosen name. Oracle:Aftermath (Cast this spell only from your graveyard. Then exile it.)\nChoose a card name. Until your next turn, your opponents can't cast spells with the chosen name.