mirror of
https://github.com/correl/mage.git
synced 2024-11-29 03:00:12 +00:00
* Fixed that Soulfire Grand Master did not work for adventure or split cards (fixes #6182).
This commit is contained in:
parent
afbae25fd1
commit
7575510c85
3 changed files with 111 additions and 51 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue