mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 21:02:08 -08:00
* Fixed a bug where wrongly a card object was moved for a copied spell.
This commit is contained in:
parent
69d3bc0575
commit
e51c4d5f67
9 changed files with 142 additions and 39 deletions
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package org.mage.test.cards.copy;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
|
@ -39,15 +38,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
*/
|
||||
public class SpelltwineTest extends CardTestPlayerBase {
|
||||
|
||||
|
||||
/**
|
||||
* Spelltwine
|
||||
* Sorcery, 5U (6)
|
||||
* Exile target instant or sorcery card from your graveyard and target instant
|
||||
* or sorcery card from an opponent's graveyard. Copy those cards. Cast the
|
||||
* copies if able without paying their mana costs. Exile Spelltwine.
|
||||
*
|
||||
*/
|
||||
* Spelltwine Sorcery, 5U (6) Exile target instant or sorcery card from your
|
||||
* graveyard and target instant or sorcery card from an opponent's
|
||||
* graveyard. Copy those cards. Cast the copies if able without paying their
|
||||
* mana costs. Exile Spelltwine.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testCopyCards() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
|
||||
|
|
@ -66,7 +63,55 @@ public class SpelltwineTest extends CardTestPlayerBase {
|
|||
assertExileCount("Lightning Bolt", 1);
|
||||
assertExileCount("Shock", 1);
|
||||
assertLife(playerB, 15);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* In a game of Commander, I cast Spelltwine, targeting Impulse and
|
||||
* Blasphemous Act. This triggered my Mirari, which I paid the 3 and copied
|
||||
* the Spelltwine. I chose new targets for the copy, naming Path to Exile
|
||||
* and Shape Anew. Somehow, the original Spelltwine was completely lost
|
||||
* after this, failing to be in the stack box or resolve all.
|
||||
*/
|
||||
@Test
|
||||
public void testCopyCardsMirari() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
|
||||
// Exile target instant or sorcery card from your graveyard and target instant or sorcery card from an opponent's graveyard.
|
||||
// Copy those cards. Cast the copies if able without paying their mana costs. Exile Spelltwine.
|
||||
addCard(Zone.HAND, playerA, "Spelltwine"); // {5}{U}
|
||||
// Look at the top four cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Impulse");
|
||||
// You draw two cards and you lose 2 life.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Night's Whisper");
|
||||
// Blasphemous Act costs {1} less to cast for each creature on the battlefield.
|
||||
// Blasphemous Act deals 13 damage to each creature.
|
||||
addCard(Zone.GRAVEYARD, playerB, "Blasphemous Act");
|
||||
// Draw two cards.
|
||||
addCard(Zone.GRAVEYARD, playerB, "Divination");
|
||||
|
||||
// Whenever you cast an instant or sorcery spell, you may pay {3}. If you do, copy that spell. You may choose new targets for the copy.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mirari", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spelltwine");
|
||||
addTarget(playerA, "Impulse");
|
||||
addTarget(playerA, "Blasphemous Act");
|
||||
setChoice(playerA, "Yes"); // pay {3} and copy spell
|
||||
setChoice(playerA, "Yes"); // Change targets
|
||||
addTarget(playerA, "Night's Whisper");
|
||||
addTarget(playerA, "Divination");
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertExileCount("Impulse", 1);
|
||||
assertExileCount("Blasphemous Act", 1);
|
||||
assertExileCount("Spelltwine", 1);
|
||||
assertExileCount("Night's Whisper", 1);
|
||||
assertExileCount("Divination", 1);
|
||||
|
||||
assertHandCount(playerA, 5);
|
||||
|
||||
assertLife(playerA, 18);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ import mage.target.TargetSource;
|
|||
import mage.target.TargetSpell;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardInOpponentsGraveyard;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.target.common.TargetCreaturePermanentAmount;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
import mage.util.MessageToClient;
|
||||
|
|
@ -785,6 +787,57 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (target instanceof TargetCardInYourGraveyard) {
|
||||
for (String targetDefinition : targets) {
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName : targetList) {
|
||||
for (Card card : computerPlayer.getGraveyard().getCards(((TargetCardInYourGraveyard) target).getFilter(), game)) {
|
||||
if (card.getName().equals(targetName) || (card.getName() + "-" + card.getExpansionSetCode()).equals(targetName)) {
|
||||
if (((TargetCardInYourGraveyard) target).canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
targetFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetFound) {
|
||||
targets.remove(targetDefinition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (target instanceof TargetCardInOpponentsGraveyard) {
|
||||
for (String targetDefinition : targets) {
|
||||
String[] targetList = targetDefinition.split("\\^");
|
||||
boolean targetFound = false;
|
||||
|
||||
for (String targetName : targetList) {
|
||||
IterateOpponentsGraveyards:
|
||||
for (UUID opponentId : game.getState().getPlayersInRange(getId(), game)) {
|
||||
if (computerPlayer.hasOpponent(opponentId, game)) {
|
||||
Player opponent = game.getPlayer(opponentId);
|
||||
for (Card card : opponent.getGraveyard().getCards(((TargetCardInOpponentsGraveyard) target).getFilter(), game)) {
|
||||
if (card.getName().equals(targetName) || (card.getName() + "-" + card.getExpansionSetCode()).equals(targetName)) {
|
||||
if (((TargetCardInOpponentsGraveyard) target).canTarget(abilityControllerId, card.getId(), source, game) && !target.getTargets().contains(card.getId())) {
|
||||
target.add(card.getId(), game);
|
||||
targetFound = true;
|
||||
break IterateOpponentsGraveyards;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetFound) {
|
||||
targets.remove(targetDefinition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (target instanceof TargetSpell) {
|
||||
for (String targetDefinition : targets) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue