* Fixed that Soulfire Grand Master did not work for adventure or split cards (fixes #6182).

This commit is contained in:
LevelX2 2020-01-14 23:26:04 +01:00
parent afbae25fd1
commit 7575510c85
3 changed files with 111 additions and 51 deletions

View file

@ -1,5 +1,6 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -10,9 +11,11 @@ import mage.abilities.effects.Effect;
import mage.abilities.effects.GainAbilitySpellsEffect; import mage.abilities.effects.GainAbilitySpellsEffect;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.LifelinkAbility;
import mage.cards.AdventureCardSpell;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.cards.SplitCardHalf;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.FilterObject; import mage.filter.FilterObject;
@ -23,8 +26,6 @@ import mage.game.events.ZoneChangeEvent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
* @author LevelX2 * @author LevelX2
*/ */
@ -99,12 +100,10 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect
@Override @Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) { public boolean replaceEvent(GameEvent event, Ability source, Game game) {
MageObject mageObject = game.getObject(spellId); Spell spell = (Spell) game.getStack().getFirst();
if (!(mageObject instanceof Spell) || mageObject.isCopy()) { if (!spell.isCopy() && !spell.isCountered()) {
return false;
} else {
Card sourceCard = game.getCard(spellId); Card sourceCard = game.getCard(spellId);
if (sourceCard != null) { if (sourceCard != null && Zone.STACK.equals(game.getState().getZone(spellId))) {
Player player = game.getPlayer(sourceCard.getOwnerId()); Player player = game.getPlayer(sourceCard.getOwnerId());
if (player != null) { if (player != null) {
player.moveCards(sourceCard, Zone.HAND, source, game); player.moveCards(sourceCard, Zone.HAND, source, game);
@ -141,12 +140,20 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect
if (zEvent.getFromZone() == Zone.STACK if (zEvent.getFromZone() == Zone.STACK
&& zEvent.getToZone() == Zone.GRAVEYARD && zEvent.getToZone() == Zone.GRAVEYARD
&& event.getTargetId().equals(spellId)) { && event.getTargetId().equals(spellId)) {
Spell spell = game.getStack().getSpell(spellId); if (game.getStack().getFirst() instanceof Spell) {
if (spell != null && !spell.isCountered()) { Card cardOfSpell = ((Spell) game.getStack().getFirst()).getCard();
if (cardOfSpell instanceof SplitCardHalf) {
return ((SplitCardHalf) cardOfSpell).getParentCard().getId().equals(spellId);
} else if (cardOfSpell instanceof AdventureCardSpell) {
return (((AdventureCardSpell) cardOfSpell).getParentCard().getId().equals(spellId));
} else {
if (cardOfSpell.getId().equals(spellId)) {
return true; return true;
} }
} }
} }
}
}
return false; return false;
} }

View file

@ -0,0 +1,52 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.test.cards.cost.splitcards;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class SplitCardsTest extends CardTestPlayerBase {
@Test
public void testReturnCardFromSoulfireGrandMaster() {
// Total CMC of Failure // Comply is 3, so should be exiled by Transgress the Mind.
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 6);
// Lifelink
// Instant and sorcery spells you control have lifelink.
// {2}{U/R}{U/R}: The next time you cast an instant or sorcery spell from your hand this turn, put that card into your hand instead of your graveyard as it resolves.
addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master");
// Fire - Instant {1}{R}
// Fire deals 2 damage divided as you choose among one or two target creatures and/or players.
// Ice - Instant {1}{U}
// Tap target permanent.
// Draw a card.
addCard(Zone.HAND, playerA, "Fire // Ice");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{U/R}{U/R}");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Fire", playerB);
addTargetAmount(playerA, "targetPlayer=PlayerB", 2);
setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
assertAllCommandsUsed();
assertLife(playerA, 22);
assertLife(playerB, 18);
assertHandCount(playerA, "Fire // Ice", 1);
}
}

View file

@ -1,5 +1,10 @@
package org.mage.test.player; package org.mage.test.player;
import java.io.Serializable;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.MageItem; import mage.MageItem;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference; import mage.MageObjectReference;
@ -56,13 +61,6 @@ import mage.util.CardUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
import java.io.Serializable;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*; import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*;
/** /**
@ -333,6 +331,9 @@ public class TestPlayer implements Player {
if (ability.getTargets().isEmpty()) { if (ability.getTargets().isEmpty()) {
throw new UnsupportedOperationException("Ability has no targets, but there is a player target set - " + ability.toString()); throw new UnsupportedOperationException("Ability has no targets, but there is a player target set - " + ability.toString());
} }
if (ability.getTargets().get(0) instanceof TargetAmount) {
return true; // targetAmount have to be set by setTargetAmount in the test script
}
ability.getTargets().get(0).addTarget(player.getId(), ability, game); ability.getTargets().get(0).addTarget(player.getId(), ability, game);
targetsSet++; targetsSet++;
break; break;
@ -1287,7 +1288,7 @@ public class TestPlayer implements Player {
UUID defenderId = null; UUID defenderId = null;
boolean mustAttackByAction = false; boolean mustAttackByAction = false;
boolean madeAttackByAction = false; boolean madeAttackByAction = false;
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext(); ) { for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext();) {
PlayerAction action = it.next(); PlayerAction action = it.next();
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) { if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) {
mustAttackByAction = true; mustAttackByAction = true;